Ejemplo n.º 1
0
	void updateEntry()
	{
		// Read file
		MemChunk data;
		data.importFile(filename);

		// Read image
		SImage image;
		image.open(data, 0, "png");
		image.convertPaletted(&palette);

		// Convert image to entry gfx format
		SIFormat* format = SIFormat::getFormat(gfx_format);
		if (format)
		{
			MemChunk conv_data;
			if (format->saveImage(image, conv_data, &palette))
			{
				// Update entry data
				entry->importMemChunk(conv_data);
				EntryOperations::setGfxOffsets(entry, offsets.x, offsets.y);
			}
			else
			{
				LOG_MESSAGE(1, "Unable to convert external png to %s", format->getName());
			}
		}
	}
Ejemplo n.º 2
0
/* EntryOperations::gfxConvert
 * Converts the image [entry] to [target_format], using conversion
 * options specified in [opt] and converting to [target_colformat]
 * colour format if possible. Returns false if the conversion failed,
 * true otherwise
 *******************************************************************/
bool EntryOperations::gfxConvert(ArchiveEntry* entry, string target_format, SIFormat::convert_options_t opt, int target_colformat)
{
	// Init variables
	SImage image;

	// Get target image format
	SIFormat* fmt = SIFormat::getFormat(target_format);
	if (fmt == SIFormat::unknownFormat())
		return false;

	// Check format and target colour type are compatible
	if (target_colformat >= 0 && !fmt->canWriteType((SIType)target_colformat))
	{
		if (target_colformat == RGBA)
			wxLogMessage("Format \"%s\" cannot be written as RGBA data", fmt->getName());
		else if (target_colformat == PALMASK)
			wxLogMessage("Format \"%s\" cannot be written as paletted data", fmt->getName());

		return false;
	}

	// Load entry to image
	Misc::loadImageFromEntry(&image, entry);

	// Check if we can write the image to the target format
	int writable = fmt->canWrite(image);
	if (writable == SIFormat::NOTWRITABLE)
	{
		wxLogMessage("Entry \"%s\" could not be converted to target format \"%s\"", entry->getName(), fmt->getName());
		return false;
	}
	else if (writable == SIFormat::CONVERTIBLE)
		fmt->convertWritable(image, opt);

	// Now we apply the target colour format (if any)
	if (target_colformat == PALMASK)
		image.convertPaletted(opt.pal_target, opt.pal_current);
	else if (target_colformat == RGBA)
		image.convertRGBA(opt.pal_current);

	// Finally, write new image data back to the entry
	fmt->saveImage(image, entry->getMCData(), opt.pal_target);

	return true;
}
Ejemplo n.º 3
0
/* GfxEntryPanel::handleAction
 * Handles the action [id]. Returns true if the action was handled,
 * false otherwise
 *******************************************************************/
bool GfxEntryPanel::handleAction(string id)
{
	// Don't handle actions if hidden
	if (!isActivePanel())
		return false;

	// We're only interested in "pgfx_" actions
	if (!id.StartsWith("pgfx_"))
		return false;

	// Mirror
	if (id == "pgfx_mirror")
	{
		// Mirror X
		getImage()->mirror(false);

		// Update UI
		gfx_canvas->updateImageTexture();
		gfx_canvas->Refresh();

		// Update variables
		image_data_modified = true;
		setModified();
	}

	// Flip
	else if (id == "pgfx_flip")
	{
		// Mirror Y
		getImage()->mirror(true);

		// Update UI
		gfx_canvas->updateImageTexture();
		gfx_canvas->Refresh();

		// Update variables
		image_data_modified = true;
		setModified();
	}

	// Rotate
	else if (id == "pgfx_rotate")
	{
		// Prompt for rotation angle
		string angles[] = { "90", "180", "270" };
		int choice = wxGetSingleChoiceIndex("Select rotation angle", "Rotate", 3, angles, 0);

		// Rotate image
		switch (choice)
		{
		case 0:
			getImage()->rotate(90);
			break;
		case 1:
			getImage()->rotate(180);
			break;
		case 2:
			getImage()->rotate(270);
			break;
		default: break;
		}

		// Update UI
		gfx_canvas->updateImageTexture();
		gfx_canvas->Refresh();

		// Update variables
		image_data_modified = true;
		setModified();
	}

	// Translate
	else if (id == "pgfx_translate")
	{
		// Create translation editor dialog
		Palette8bit* pal = theMainWindow->getPaletteChooser()->getSelectedPalette();
		TranslationEditorDialog ted(theMainWindow, pal, " Colour Remap", gfx_canvas->getImage());

		// Create translation to edit
		ted.openTranslation(prev_translation);

		// Show the dialog
		if (ted.ShowModal() == wxID_OK)
		{
			// Apply translation to image
			getImage()->applyTranslation(&ted.getTranslation(), pal);

			// Update UI
			gfx_canvas->updateImageTexture();
			gfx_canvas->Refresh();

			// Update variables
			image_data_modified = true;
			gfx_canvas->updateImageTexture();
			setModified();
			prev_translation.copy(ted.getTranslation());
		}
	}

	// Colourise
	else if (id == "pgfx_colourise")
	{
		Palette8bit* pal = theMainWindow->getPaletteChooser()->getSelectedPalette();
		GfxColouriseDialog gcd(theMainWindow, entry, pal);
		gcd.setColour(last_colour);

		// Show colourise dialog
		if (gcd.ShowModal() == wxID_OK)
		{
			// Colourise image
			getImage()->colourise(gcd.getColour(), pal);

			// Update UI
			gfx_canvas->updateImageTexture();
			gfx_canvas->Refresh();

			// Update variables
			image_data_modified = true;
			Refresh();
			setModified();
		}
		rgba_t gcdcol = gcd.getColour();
		last_colour = S_FMT("RGB(%d, %d, %d)", gcdcol.r, gcdcol.g, gcdcol.b);
	}

	// Tint
	else if (id == "pgfx_tint")
	{
		Palette8bit* pal = theMainWindow->getPaletteChooser()->getSelectedPalette();
		GfxTintDialog gtd(theMainWindow, entry, pal);
		gtd.setValues(last_tint_colour, last_tint_amount);

		// Show tint dialog
		if (gtd.ShowModal() == wxID_OK)
		{
			// Tint image
			getImage()->tint(gtd.getColour(), gtd.getAmount(), pal);

			// Update UI
			gfx_canvas->updateImageTexture();
			gfx_canvas->Refresh();

			// Update variables
			image_data_modified = true;
			Refresh();
			setModified();
		}
		rgba_t gtdcol = gtd.getColour();
		last_tint_colour = S_FMT("RGB(%d, %d, %d)", gtdcol.r, gtdcol.g, gtdcol.b);
		last_tint_amount = (int)(gtd.getAmount() * 100.0);
	}

	// Crop
	else if (id == "pgfx_crop")
	{
		Palette8bit* pal = theMainWindow->getPaletteChooser()->getSelectedPalette();
		GfxCropDialog gcd(theMainWindow, entry, pal);

		// Show crop dialog
		if (gcd.ShowModal() == wxID_OK)
		{
			// stuff
		}
	}

	// alPh/tRNS
	else if (id == "pgfx_alph" || id == "pgfx_trns")
	{
		setModified();
		Refresh();
	}

	// Optimize PNG
	else if (id == "pgfx_pngopt")
	{
		// This is a special case. If we set the entry as modified, SLADE will prompt
		// to save it, rewriting the entry and cancelling the optimization done...
		if (EntryOperations::optimizePNG(entry))
			setModified(false);
		else
			wxMessageBox("Warning: Couldn't optimize this image, check console log for info", "Warning", wxOK|wxCENTRE|wxICON_WARNING);
		Refresh();
	}

	// Extract all
	else if (id == "pgfx_extract")
	{
		extractAll();
	}

	// Convert
	else if (id == "pgfx_convert")
	{
		GfxConvDialog gcd(theMainWindow);
		gcd.CenterOnParent();
		gcd.openEntry(entry);

		gcd.ShowModal();

		if (gcd.itemModified(0))
		{
			// Get image and conversion info
			SImage* image = gcd.getItemImage(0);
			SIFormat* format = gcd.getItemFormat(0);

			// Write converted image back to entry
			format->saveImage(*image, entry_data, gcd.getItemPalette(0));
			// This makes the "save" button (and the setModified stuff) redundant and confusing!
			// The alternative is to save to entry effectively (uncomment the importMemChunk line)
			// but remove the setModified and image_data_modified lines, and add a call to refresh
			// to get the PNG tRNS status back in sync.
			//entry->importMemChunk(entry_data);
			image_data_modified = true;
			setModified();

			// Fix tRNS status if we converted to paletted PNG
			int MENU_GFXEP_PNGOPT = theApp->getAction("pgfx_pngopt")->getWxId();
			int MENU_GFXEP_ALPH = theApp->getAction("pgfx_alph")->getWxId();
			int MENU_GFXEP_TRNS = theApp->getAction("pgfx_trns")->getWxId();
			int MENU_ARCHGFX_EXPORTPNG = theApp->getAction("arch_gfx_exportpng")->getWxId();
			if (format->getName() == "PNG")
			{
				ArchiveEntry temp;
				temp.importMemChunk(entry_data);
				temp.setType(EntryType::getType("png"));
				menu_custom->Enable(MENU_GFXEP_ALPH, true);
				menu_custom->Enable(MENU_GFXEP_TRNS, true);
				menu_custom->Check(MENU_GFXEP_TRNS, EntryOperations::gettRNSChunk(&temp));
				menu_custom->Enable(MENU_ARCHGFX_EXPORTPNG, false);
				menu_custom->Enable(MENU_GFXEP_PNGOPT, true);
				toolbar->enableGroup("PNG", true);
			}
			else
			{
				menu_custom->Enable(MENU_GFXEP_ALPH, false);
				menu_custom->Enable(MENU_GFXEP_TRNS, false);
				menu_custom->Enable(MENU_ARCHGFX_EXPORTPNG, true);
				menu_custom->Enable(MENU_GFXEP_PNGOPT, false);
				toolbar->enableGroup("PNG", false);
			}

			// Refresh
			getImage()->open(entry_data, 0, format->getId());
			gfx_canvas->Refresh();
		}
	}

	// Unknown action
	else
		return false;

	// Action handled
	return true;
}
Ejemplo n.º 4
0
/* GfxEntryPanel::saveEntry
 * Saves any changes to the entry
 *******************************************************************/
bool GfxEntryPanel::saveEntry()
{
	// Write new image data if modified
	bool ok = true;
	if (image_data_modified)
	{
		SImage* image = getImage();
		SIFormat* format = image->getFormat();

		string error = "";
		ok = false;
		int writable = format->canWrite(*image);
		if (format == SIFormat::unknownFormat())
			error = "Image is of unknown format";
		else if (writable == SIFormat::NOTWRITABLE)
			error = S_FMT("Writing unsupported for format \"%s\"", format->getName());
		else
		{
			// Convert image if necessary (using default options)
			if (writable == SIFormat::CONVERTIBLE)
			{
				format->convertWritable(*image, SIFormat::convert_options_t());
				wxLogMessage("Image converted for writing");
			}

			if (format->saveImage(*image, entry->getMCData(), gfx_canvas->getPalette()))
				ok = true;
			else
				error = "Error writing image";
		}

		if (ok)
		{
			// Set modified
			entry->setState(1);

			// Re-detect type
			EntryType* oldtype = entry->getType();
			EntryType::detectEntryType(entry);

			// Update extension if type changed
			if (oldtype != entry->getType())
				entry->setExtensionByType();
		}
		else
			wxMessageBox(wxString("Cannot save changes to image: ") + error, "Error", wxICON_ERROR);
	}
	// Otherwise just set offsets
	else
		EntryOperations::setGfxOffsets(entry, spin_xoffset->GetValue(), spin_yoffset->GetValue());

	// Apply alPh/tRNS options
	if (entry->getType()->getFormat() == "img_png")
	{
		bool alph = EntryOperations::getalPhChunk(entry);
		bool trns = EntryOperations::gettRNSChunk(entry);

		if (alph != menu_custom->IsChecked(theApp->getAction("pgfx_alph")->getWxId()))
			EntryOperations::modifyalPhChunk(entry, !alph);
		if (trns != menu_custom->IsChecked(theApp->getAction("pgfx_trns")->getWxId()))
			EntryOperations::modifytRNSChunk(entry, !trns);
	}

	if (ok)
		setModified(false);

	return ok;
}