mirror of
https://github.com/amyinspace/MagicSetEditor2.git
synced 2026-06-13 05:57:00 -04:00
Fix #10: Use of saturate function almost always causes a crash.
saturate: fix possible division by 0 SaturateImage: fix: had two 'image' members, one inherited, one nullptr, which caused a crash git-svn-id: svn://svn.code.sf.net/p/magicseteditor/code/trunk@1458 0fc631ac-6414-0410-93d0-97cfa31319b6
This commit is contained in:
@@ -228,9 +228,6 @@ Image EnlargeImage::generate(const Options& opt) const {
|
|||||||
// done
|
// done
|
||||||
return larger;
|
return larger;
|
||||||
}
|
}
|
||||||
ImageCombine EnlargeImage::combine() const {
|
|
||||||
return image->combine();
|
|
||||||
}
|
|
||||||
bool EnlargeImage::operator == (const GeneratedImage& that) const {
|
bool EnlargeImage::operator == (const GeneratedImage& that) const {
|
||||||
const EnlargeImage* that2 = dynamic_cast<const EnlargeImage*>(&that);
|
const EnlargeImage* that2 = dynamic_cast<const EnlargeImage*>(&that);
|
||||||
return that2 && *image == *that2->image
|
return that2 && *image == *that2->image
|
||||||
@@ -242,9 +239,6 @@ bool EnlargeImage::operator == (const GeneratedImage& that) const {
|
|||||||
Image CropImage::generate(const Options& opt) const {
|
Image CropImage::generate(const Options& opt) const {
|
||||||
return image->generate(opt).Size(wxSize((int)width, (int)height), wxPoint(-(int)offset_x, -(int)offset_y));
|
return image->generate(opt).Size(wxSize((int)width, (int)height), wxPoint(-(int)offset_x, -(int)offset_y));
|
||||||
}
|
}
|
||||||
ImageCombine CropImage::combine() const {
|
|
||||||
return image->combine();
|
|
||||||
}
|
|
||||||
bool CropImage::operator == (const GeneratedImage& that) const {
|
bool CropImage::operator == (const GeneratedImage& that) const {
|
||||||
const CropImage* that2 = dynamic_cast<const CropImage*>(&that);
|
const CropImage* that2 = dynamic_cast<const CropImage*>(&that);
|
||||||
return that2 && *image == *that2->image
|
return that2 && *image == *that2->image
|
||||||
@@ -340,9 +334,6 @@ Image DropShadowImage::generate(const Options& opt) const {
|
|||||||
delete[] shadow;
|
delete[] shadow;
|
||||||
return img;
|
return img;
|
||||||
}
|
}
|
||||||
ImageCombine DropShadowImage::combine() const {
|
|
||||||
return image->combine();
|
|
||||||
}
|
|
||||||
bool DropShadowImage::operator == (const GeneratedImage& that) const {
|
bool DropShadowImage::operator == (const GeneratedImage& that) const {
|
||||||
const DropShadowImage* that2 = dynamic_cast<const DropShadowImage*>(&that);
|
const DropShadowImage* that2 = dynamic_cast<const DropShadowImage*>(&that);
|
||||||
return that2 && *image == *that2->image
|
return that2 && *image == *that2->image
|
||||||
|
|||||||
@@ -199,41 +199,34 @@ class SaturateImage : public SimpleFilterImage {
|
|||||||
virtual Image generate(const Options& opt) const;
|
virtual Image generate(const Options& opt) const;
|
||||||
virtual bool operator == (const GeneratedImage& that) const;
|
virtual bool operator == (const GeneratedImage& that) const;
|
||||||
private:
|
private:
|
||||||
GeneratedImageP image;
|
|
||||||
double amount;
|
double amount;
|
||||||
};
|
};
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : EnlargeImage
|
// ----------------------------------------------------------------------------- : EnlargeImage
|
||||||
|
|
||||||
/// Enlarge an image by adding a border around it
|
/// Enlarge an image by adding a border around it
|
||||||
class EnlargeImage : public GeneratedImage {
|
class EnlargeImage : public SimpleFilterImage {
|
||||||
public:
|
public:
|
||||||
inline EnlargeImage(const GeneratedImageP& image, double border_size)
|
inline EnlargeImage(const GeneratedImageP& image, double border_size)
|
||||||
: image(image), border_size(fabs(border_size))
|
: SimpleFilterImage(image), border_size(fabs(border_size))
|
||||||
{}
|
{}
|
||||||
virtual Image generate(const Options& opt) const;
|
virtual Image generate(const Options& opt) const;
|
||||||
virtual ImageCombine combine() const;
|
|
||||||
virtual bool operator == (const GeneratedImage& that) const;
|
virtual bool operator == (const GeneratedImage& that) const;
|
||||||
virtual bool local() const { return image->local(); }
|
|
||||||
private:
|
private:
|
||||||
GeneratedImageP image;
|
|
||||||
double border_size;
|
double border_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : CropImage
|
// ----------------------------------------------------------------------------- : CropImage
|
||||||
|
|
||||||
/// Crop an image at a certain point, to a certain size
|
/// Crop an image at a certain point, to a certain size
|
||||||
class CropImage : public GeneratedImage {
|
class CropImage : public SimpleFilterImage {
|
||||||
public:
|
public:
|
||||||
inline CropImage(const GeneratedImageP& image, double width, double height, double offset_x, double offset_y)
|
inline CropImage(const GeneratedImageP& image, double width, double height, double offset_x, double offset_y)
|
||||||
: image(image), width(width), height(height), offset_x(offset_x), offset_y(offset_y)
|
: SimpleFilterImage(image), width(width), height(height), offset_x(offset_x), offset_y(offset_y)
|
||||||
{}
|
{}
|
||||||
virtual Image generate(const Options& opt) const;
|
virtual Image generate(const Options& opt) const;
|
||||||
virtual ImageCombine combine() const;
|
|
||||||
virtual bool operator == (const GeneratedImage& that) const;
|
virtual bool operator == (const GeneratedImage& that) const;
|
||||||
virtual bool local() const { return image->local(); }
|
|
||||||
private:
|
private:
|
||||||
GeneratedImageP image;
|
|
||||||
double width, height;
|
double width, height;
|
||||||
double offset_x, offset_y;
|
double offset_x, offset_y;
|
||||||
};
|
};
|
||||||
@@ -241,18 +234,15 @@ class CropImage : public GeneratedImage {
|
|||||||
// ----------------------------------------------------------------------------- : DropShadowImage
|
// ----------------------------------------------------------------------------- : DropShadowImage
|
||||||
|
|
||||||
/// Add a drop shadow to an image
|
/// Add a drop shadow to an image
|
||||||
class DropShadowImage : public GeneratedImage {
|
class DropShadowImage : public SimpleFilterImage {
|
||||||
public:
|
public:
|
||||||
inline DropShadowImage(const GeneratedImageP& image, double offset_x, double offset_y, double shadow_alpha, double shadow_blur_radius, Color shadow_color)
|
inline DropShadowImage(const GeneratedImageP& image, double offset_x, double offset_y, double shadow_alpha, double shadow_blur_radius, Color shadow_color)
|
||||||
: image(image), offset_x(offset_x), offset_y(offset_y)
|
: SimpleFilterImage(image), offset_x(offset_x), offset_y(offset_y)
|
||||||
, shadow_alpha(shadow_alpha), shadow_blur_radius(shadow_blur_radius), shadow_color(shadow_color)
|
, shadow_alpha(shadow_alpha), shadow_blur_radius(shadow_blur_radius), shadow_color(shadow_color)
|
||||||
{}
|
{}
|
||||||
virtual Image generate(const Options& opt) const;
|
virtual Image generate(const Options& opt) const;
|
||||||
virtual ImageCombine combine() const;
|
|
||||||
virtual bool operator == (const GeneratedImage& that) const;
|
virtual bool operator == (const GeneratedImage& that) const;
|
||||||
virtual bool local() const { return image->local(); }
|
|
||||||
private:
|
private:
|
||||||
GeneratedImageP image;
|
|
||||||
double offset_x, offset_y;
|
double offset_x, offset_y;
|
||||||
double shadow_alpha;
|
double shadow_alpha;
|
||||||
double shadow_blur_radius;
|
double shadow_blur_radius;
|
||||||
|
|||||||
+25
-12
@@ -13,13 +13,32 @@
|
|||||||
// ----------------------------------------------------------------------------- : Saturation
|
// ----------------------------------------------------------------------------- : Saturation
|
||||||
|
|
||||||
void saturate(Image& image, double amount) {
|
void saturate(Image& image, double amount) {
|
||||||
if (amount == 0) return; // nothing to do
|
|
||||||
Byte* pix = image.GetData();
|
Byte* pix = image.GetData();
|
||||||
Byte* end = pix + image.GetWidth() * image.GetHeight() * 3;
|
Byte* end = pix + image.GetWidth() * image.GetHeight() * 3;
|
||||||
if (amount > 0) {
|
// the formula for saturation is
|
||||||
amount = min(amount,0.99);
|
// rgb' = (rgb - amount * avg) / (1 - amount)
|
||||||
int factor = int(256 * amount);
|
// if amount >= 1 then this is some kind of inversion
|
||||||
int div = 768 - 3 * factor;
|
// if amount > 0 then use formula directly
|
||||||
|
// if amount < 0 then de-saturate instead:
|
||||||
|
// rgb = rgb' + -amount*avg - -amount*rgb'
|
||||||
|
// = rgb' * (1 - -amount) + -amount*avg
|
||||||
|
// if amount < -1 then we are left with just the average
|
||||||
|
int factor = int(256 * amount);
|
||||||
|
if (factor == 0) {
|
||||||
|
return; // nothing to do
|
||||||
|
} else if (factor == 256) {
|
||||||
|
// super crazy saturation: division by zero
|
||||||
|
// if we take infty to be 255, then it is a >avg test
|
||||||
|
while (pix != end) {
|
||||||
|
int r = pix[0], g = pix[1], b = pix[2];
|
||||||
|
pix[0] = r+r > g+b ? 255 : 0;
|
||||||
|
pix[1] = g+g > b+r ? 255 : 0;
|
||||||
|
pix[2] = b+b > r+g ? 255 : 0;
|
||||||
|
pix += 3;
|
||||||
|
}
|
||||||
|
} else if (factor > 0) {
|
||||||
|
int div = 768 - 3 * factor;
|
||||||
|
assert(div > 0);
|
||||||
while (pix != end) {
|
while (pix != end) {
|
||||||
int r = pix[0], g = pix[1], b = pix[2];
|
int r = pix[0], g = pix[1], b = pix[2];
|
||||||
int avg = factor*(r+g+b);
|
int avg = factor*(r+g+b);
|
||||||
@@ -28,14 +47,8 @@ void saturate(Image& image, double amount) {
|
|||||||
pix[2] = col((768*b - avg) / div);
|
pix[2] = col((768*b - avg) / div);
|
||||||
pix += 3;
|
pix += 3;
|
||||||
}
|
}
|
||||||
} else if (amount < -0.99) {
|
|
||||||
while (pix != end) {
|
|
||||||
int r = pix[0], g = pix[1], b = pix[2];
|
|
||||||
pix[0] = pix[1] = pix[2] = (r+g+b)/3;
|
|
||||||
pix += 3;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
int factor1 = int(256 * -amount);
|
int factor1 = -factor;
|
||||||
int factor2 = 768 - 3*factor1;
|
int factor2 = 768 - 3*factor1;
|
||||||
while (pix != end) {
|
while (pix != end) {
|
||||||
int r = pix[0], g = pix[1], b = pix[2];
|
int r = pix[0], g = pix[1], b = pix[2];
|
||||||
|
|||||||
Reference in New Issue
Block a user