HueSaturation can be used for palette and pixels on indexed images now

If there are an active selection: we adjust pixels, if there is no
selection, we adjust palette entries.
This commit is contained in:
David Capello 2017-06-21 23:13:43 -03:00
parent 4834ff3320
commit 85b7996e9a
5 changed files with 95 additions and 90 deletions

View File

@ -431,4 +431,10 @@ void FilterManagerImpl::restoreSpritePalette()
m_site.sprite()->setPalette(m_oldPalette.get(), false);
}
bool FilterManagerImpl::isMaskActive() const
{
return static_cast<const app::Document*>(m_site.document())
->isMaskVisible();
}
} // namespace app

View File

@ -104,6 +104,7 @@ namespace app {
int x() const override { return m_bounds.x; }
int y() const override { return m_bounds.y+m_row; }
bool isFirstRow() const override { return m_row == 0; }
bool isMaskActive() const override;
// FilterIndexedData implementation
const doc::Palette* getPalette() const override;

View File

@ -73,6 +73,10 @@ namespace filters {
// to the palette in the first row.
virtual bool isFirstRow() const = 0;
// Returns true if the mask is actived (so we are applying the
// filter just to a part of the sprite).
virtual bool isMaskActive() const = 0;
};
} // namespace filters

View File

@ -64,50 +64,17 @@ void HueSaturationFilter::applyToRgba(FilterManager* filterMgr)
uint32_t* dst_address = (uint32_t*)filterMgr->getDestinationAddress();
const int w = filterMgr->getWidth();
const Target target = filterMgr->getTarget();
int x, c, r, g, b, a;
for (x=0; x<w; x++) {
for (int x=0; x<w; x++) {
if (filterMgr->skipPixel()) {
++src_address;
++dst_address;
continue;
}
c = *(src_address++);
r = rgba_getr(c);
g = rgba_getg(c);
b = rgba_getb(c);
a = rgba_geta(c);
{
gfx::Hsl hsl(gfx::Rgb(r, g, b));
double h = hsl.hue() + m_h;
while (h < 0.0)
h += 360.0;
h = std::fmod(h, 360.0);
double s = hsl.saturation() + m_s;
s = MID(0.0, s, 1.0);
double l = hsl.lightness() + m_l;
l = MID(0.0, l, 1.0);
hsl.hue(h);
hsl.saturation(s);
hsl.lightness(l);
gfx::Rgb rgb(hsl);
if (target & TARGET_RED_CHANNEL ) r = rgb.red();
if (target & TARGET_GREEN_CHANNEL) g = rgb.green();
if (target & TARGET_BLUE_CHANNEL ) b = rgb.blue();
if (a && (target & TARGET_ALPHA_CHANNEL))
a = MID(0, a+m_a, 255);
}
*(dst_address++) = rgba(r, g, b, a);
color_t c = *(src_address++);
applyHslFilterToRgb(target, c);
*(dst_address++) = c;
}
}
@ -117,19 +84,17 @@ void HueSaturationFilter::applyToGrayscale(FilterManager* filterMgr)
uint16_t* dst_address = (uint16_t*)filterMgr->getDestinationAddress();
const int w = filterMgr->getWidth();
const Target target = filterMgr->getTarget();
int x, c, k, a;
for (x=0; x<w; x++) {
for (int x=0; x<w; x++) {
if (filterMgr->skipPixel()) {
++src_address;
++dst_address;
continue;
}
c = *(src_address++);
k = graya_getv(c);
a = graya_geta(c);
color_t c = *(src_address++);
int k = graya_getv(c);
int a = graya_geta(c);
{
gfx::Hsl hsl(gfx::Rgb(k, k, k));
@ -152,62 +117,87 @@ void HueSaturationFilter::applyToGrayscale(FilterManager* filterMgr)
void HueSaturationFilter::applyToIndexed(FilterManager* filterMgr)
{
if (!filterMgr->isFirstRow())
return;
FilterIndexedData* fid = filterMgr->getIndexedData();
const Target target = filterMgr->getTarget();
FilterIndexedData* fid = filterMgr->getIndexedData();
const Palette* pal = fid->getPalette();
PalettePicks picks = fid->getPalettePicks();
Palette* newPal = fid->getNewPalette();
int i = 0;
for (bool state : picks) {
if (!state) {
// Apply filter to color palette
if (!filterMgr->isMaskActive()) {
if (!filterMgr->isFirstRow())
return;
PalettePicks picks = fid->getPalettePicks();
Palette* newPal = fid->getNewPalette();
int i = 0;
for (bool state : picks) {
if (!state) {
++i;
continue;
}
color_t c = pal->getEntry(i);
applyHslFilterToRgb(target, c);
newPal->setEntry(i, c);
++i;
continue;
}
}
// Apply filter to color region
else {
const RgbMap* rgbmap = fid->getRgbMap();
const uint8_t* src_address = (uint8_t*)filterMgr->getSourceAddress();
uint8_t* dst_address = (uint8_t*)filterMgr->getDestinationAddress();
const int w = filterMgr->getWidth();
color_t c = pal->getEntry(i);
int r = rgba_getr(c);
int g = rgba_getg(c);
int b = rgba_getb(c);
int a = rgba_geta(c);
for (int x=0; x<w; x++) {
if (filterMgr->skipPixel()) {
++src_address;
++dst_address;
continue;
}
{
gfx::Hsl hsl(gfx::Rgb(r, g, b));
double h = hsl.hue() + m_h;
while (h < 0.0) h += 360.0;
h = std::fmod(h, 360.0);
double s = hsl.saturation() + m_s;
s = MID(0.0, s, 1.0);
double l = hsl.lightness() + m_l;
l = MID(0.0, l, 1.0);
hsl.hue(h);
hsl.saturation(s);
hsl.lightness(l);
gfx::Rgb rgb(hsl);
if (target & TARGET_RED_CHANNEL ) r = rgb.red();
if (target & TARGET_GREEN_CHANNEL) g = rgb.green();
if (target & TARGET_BLUE_CHANNEL ) b = rgb.blue();
if (a && (target & TARGET_ALPHA_CHANNEL))
a = MID(0, a+m_a, 255);
if (target & (TARGET_RED_CHANNEL |
TARGET_GREEN_CHANNEL |
TARGET_BLUE_CHANNEL |
TARGET_ALPHA_CHANNEL))
c = rgba(r, g, b, a);
color_t c = pal->getEntry(*(src_address++));
applyHslFilterToRgb(target, c);
*(dst_address++) = rgbmap->mapColor(rgba_getr(c),
rgba_getg(c),
rgba_getb(c),
rgba_geta(c));
}
newPal->setEntry(i, c);
++i;
}
}
void HueSaturationFilter::applyHslFilterToRgb(
const Target target, doc::color_t& c)
{
int r = rgba_getr(c);
int g = rgba_getg(c);
int b = rgba_getb(c);
int a = rgba_geta(c);
gfx::Hsl hsl(gfx::Rgb(r, g, b));
double h = hsl.hue() + m_h;
while (h < 0.0) h += 360.0;
h = std::fmod(h, 360.0);
double s = hsl.saturation() + m_s;
s = MID(0.0, s, 1.0);
double l = hsl.lightness() + m_l;
l = MID(0.0, l, 1.0);
hsl.hue(h);
hsl.saturation(s);
hsl.lightness(l);
gfx::Rgb rgb(hsl);
if (target & TARGET_RED_CHANNEL ) r = rgb.red();
if (target & TARGET_GREEN_CHANNEL) g = rgb.green();
if (target & TARGET_BLUE_CHANNEL ) b = rgb.blue();
if (a && (target & TARGET_ALPHA_CHANNEL))
a = MID(0, a+m_a, 255);
c = rgba(r, g, b, a);
}
} // namespace filters

View File

@ -8,7 +8,9 @@
#define FILTERS_HUE_SATURATION_FILTER_H_INCLUDED
#pragma once
#include "doc/color.h"
#include "filters/filter.h"
#include "filters/target.h"
namespace filters {
@ -28,6 +30,8 @@ namespace filters {
void applyToIndexed(FilterManager* filterMgr);
private:
void applyHslFilterToRgb(const Target target, doc::color_t& color);
double m_h, m_s, m_l;
int m_a;
};