diff --git a/Greenshot/Drawing/Filters/AbstractFilter.cs b/Greenshot/Drawing/Filters/AbstractFilter.cs
index 4ce539b17..ef47a50c0 100644
--- a/Greenshot/Drawing/Filters/AbstractFilter.cs
+++ b/Greenshot/Drawing/Filters/AbstractFilter.cs
@@ -47,7 +47,9 @@ namespace Greenshot.Drawing.Filters {
get { return invert; }
set { invert=value; OnPropertyChanged("Invert"); }
}
+ [NonSerialized]
protected BitmapBuffer bbb;
+
protected Rectangle applyRect;
protected DrawableContainer parent;
public DrawableContainer Parent {
diff --git a/GreenshotPlugin/Core/BitmapBuffer.cs b/GreenshotPlugin/Core/BitmapBuffer.cs
index ea5d755be..6a99c499d 100644
--- a/GreenshotPlugin/Core/BitmapBuffer.cs
+++ b/GreenshotPlugin/Core/BitmapBuffer.cs
@@ -28,7 +28,6 @@ namespace GreenshotPlugin.Core {
/// The BitmapBuffer is exactly what it says, it buffers a Bitmap.
/// And it is possible to Draw on the Bitmap with direct memory access for better performance
///
- [Serializable()]
public unsafe class BitmapBuffer : IDisposable {
private static log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(BitmapBuffer));
private bool clone;
@@ -36,6 +35,7 @@ namespace GreenshotPlugin.Core {
// Used for indexed images
private Color[] colorEntries;
+
public static Color BackgroundBlendColor {
get;
set;
@@ -70,35 +70,21 @@ namespace GreenshotPlugin.Core {
}
}
- [NonSerialized]
private BitmapData bmData;
- [NonSerialized]
private Rectangle rect;
- [NonSerialized]
private byte* pointer;
- [NonSerialized]
private int* intPointer;
- [NonSerialized]
private int stride; /* bytes per pixel row */
- [NonSerialized]
private int aIndex = -1;
- [NonSerialized]
private int rIndex = -1;
- [NonSerialized]
private int gIndex = -1;
- [NonSerialized]
private int bIndex = -1;
- [NonSerialized]
private int bytesPerPixel;
- [NonSerialized]
private bool bitsLocked = false;
public Size Size {
get {return rect.Size;}
}
- public int Length {
- get {return rect.Width*rect.Height;}
- }
public int Width {
get {return rect.Width;}
}
@@ -204,29 +190,6 @@ namespace GreenshotPlugin.Core {
bmData = null;
pointer = null;
}
-
- /**
- * This is called when deserializing the object
- */
- public BitmapBuffer(SerializationInfo info, StreamingContext ctxt) {
- this.bitmap = (Bitmap)info.GetValue("bitmap", typeof(Bitmap));
- this.rect = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
- // The rest will be set when Lock is called
- }
-
- /**
- * This is called when serializing the object
- */
- public void GetObjectData(SerializationInfo info, StreamingContext ctxt) {
- bool isLocked = bitsLocked;
- if (isLocked) {
- Unlock();
- }
- info.AddValue("bitmap", this.bitmap);
- if (isLocked) {
- Lock();
- }
- }
/**
* Lock the bitmap so we have direct access to the memory
@@ -297,51 +260,6 @@ namespace GreenshotPlugin.Core {
}
}
- ///
- /// Retrieve the color index, for 8BPP, at location x,y
- ///
- /// X coordinate
- /// Y Coordinate
- /// color index
- public byte GetColorIndexAt(int x, int y) {
- int offset = x*bytesPerPixel+y*stride;
- return pointer[offset];
- }
-
- ///
- /// Get the color for an 8-bit image
- ///
- ///
- ///
- /// Color from the palette
- public Color GetColor(int x, int y) {
- int offset = x * bytesPerPixel + y * stride;
- byte colorIndex = pointer[offset];
- return colorEntries[colorIndex];
- }
-
- ///
- /// Set the color index, for 8BPP, at location x,y
- ///
- /// X coordinate
- /// Y Coordinate
- /// Color index to set
- public void SetColorIndexAt(int x, int y, byte colorIndex) {
- int offset = x * bytesPerPixel + y * stride;
- pointer[offset] = colorIndex;
- }
-
- ///
- /// Use only when 32-bit bitmap!
- ///
- /// x
- /// y
- /// int with argb value
- public int GetARGB(int x, int y) {
- int offset = (y * (stride >> 2)) + x;
- return intPointer[offset];
- }
-
///
/// Use only when 32-bit bitmap!
///
@@ -370,34 +288,6 @@ namespace GreenshotPlugin.Core {
}
}
- ///
- /// Retrieve the color, without alpha (is blended), at location x,y
- /// Before the first time this is called the Lock() should be called once!
- ///
- /// X coordinate
- /// Y Coordinate
- /// Color
- public Color GetColorAtWithoutAlpha(int x, int y) {
- if (x >= 0 && y >= 0 && x < rect.Width && y < rect.Height) {
- int offset = x * bytesPerPixel + y * stride;
- int a = (aIndex == -1) ? (byte)255 : pointer[aIndex + offset];
- int red = pointer[rIndex + offset];
- int green = pointer[gIndex + offset];
- int blue = pointer[bIndex + offset];
-
- if (a < 255) {
- // As the request is to get without alpha, we blend.
- int rem = 255 - a;
- red = (red * a + BackgroundBlendColor.R * rem) / 255;
- green = (green * a + BackgroundBlendColor.G * rem) / 255;
- blue = (blue * a + BackgroundBlendColor.B * rem) / 255;
- }
- return Color.FromArgb(255, red, green, blue);
- } else {
- return Color.Empty;
- }
- }
-
/**
* Set the color at location x,y
* Before the first time this is called the Lock() should be called once!
@@ -412,20 +302,6 @@ namespace GreenshotPlugin.Core {
}
}
- /**
- * Retrieve the color at location x,y as an array
- * Before the first time this is called the Lock() should be called once!
- */
- public byte[] GetColorArrayAt(int x, int y) {
- if(x>=0 && y>=0 && x
public bool NeedsDispose {
get;
- protected set;
+ set;
}
///
@@ -116,7 +115,7 @@ namespace GreenshotPlugin.Core {
public static IFastBitmap CreateEmpty(Size newSize, PixelFormat pixelFormat, Color backgroundColor) {
Bitmap destination = ImageHelper.CreateEmpty(newSize.Width, newSize.Height, pixelFormat, backgroundColor, 96f, 96f);
IFastBitmap fastBitmap = Create(destination);
- ((FastBitmap)fastBitmap).NeedsDispose = true;
+ fastBitmap.NeedsDispose = true;
return fastBitmap;
}
@@ -152,15 +151,15 @@ namespace GreenshotPlugin.Core {
}
///
- /// Returns the underlying bitmap, do not dispose... if it's created for the FastBitmap it will be disposed!
+ /// Returns the underlying bitmap, unlocks it and prevents that it will be disposed
///
- public Bitmap Bitmap {
- get {
- if (bitsLocked) {
- throw new NotSupportedException("Can't get a locked bitmap!");
- }
- return bitmap;
+ public Bitmap UnlockAndReturnBitmap() {
+ if (bitsLocked) {
+ LOG.Warn("Unlocking the bitmap");
+ Unlock();
}
+ NeedsDispose = false;
+ return bitmap;
}
///
diff --git a/GreenshotPlugin/Core/ImageHelper.cs b/GreenshotPlugin/Core/ImageHelper.cs
index f6d234546..12996f461 100644
--- a/GreenshotPlugin/Core/ImageHelper.cs
+++ b/GreenshotPlugin/Core/ImageHelper.cs
@@ -111,19 +111,19 @@ namespace GreenshotPlugin.Core {
///
/// Private helper method for the FindAutoCropRectangle
///
- ///
+ ///
///
/// Rectangle
- private static Rectangle FindAutoCropRectangle(BitmapBuffer buffer, Point colorPoint, int cropDifference) {
+ private static Rectangle FindAutoCropRectangle(IFastBitmap fastBitmap, Point colorPoint, int cropDifference) {
Rectangle cropRectangle = Rectangle.Empty;
- Color referenceColor = buffer.GetColorAtWithoutAlpha(colorPoint.X,colorPoint.Y);
+ Color referenceColor = fastBitmap.GetColorAt(colorPoint.X, colorPoint.Y);
Point min = new Point(int.MaxValue, int.MaxValue);
Point max = new Point(int.MinValue, int.MinValue);
if (cropDifference > 0) {
- for(int y = 0; y < buffer.Height; y++) {
- for(int x = 0; x < buffer.Width; x++) {
- Color currentColor = buffer.GetColorAt(x, y);
+ for (int y = 0; y < fastBitmap.Height; y++) {
+ for (int x = 0; x < fastBitmap.Width; x++) {
+ Color currentColor = fastBitmap.GetColorAt(x, y);
int diffR = Math.Abs(currentColor.R - referenceColor.R);
int diffG = Math.Abs(currentColor.G - referenceColor.G);
int diffB = Math.Abs(currentColor.B - referenceColor.B);
@@ -136,9 +136,9 @@ namespace GreenshotPlugin.Core {
}
}
} else {
- for(int y = 0; y < buffer.Height; y++) {
- for(int x = 0; x < buffer.Width; x++) {
- Color currentColor = buffer.GetColorAtWithoutAlpha(x, y);
+ for (int y = 0; y < fastBitmap.Height; y++) {
+ for (int x = 0; x < fastBitmap.Width; x++) {
+ Color currentColor = fastBitmap.GetColorAt(x, y);
if (referenceColor.Equals(currentColor)) {
if (x < min.X) min.X = x;
if (y < min.Y) min.Y = y;
@@ -149,7 +149,7 @@ namespace GreenshotPlugin.Core {
}
}
- if (!(Point.Empty.Equals(min) && max.Equals(new Point(buffer.Width-1, buffer.Height-1)))) {
+ if (!(Point.Empty.Equals(min) && max.Equals(new Point(fastBitmap.Width - 1, fastBitmap.Height - 1)))) {
if (!(min.X == int.MaxValue || min.Y == int.MaxValue || max.X == int.MinValue || min.X == int.MinValue)) {
cropRectangle = new Rectangle(min.X, min.Y, max.X - min.X + 1, max.Y - min.Y + 1);
}
@@ -164,22 +164,22 @@ namespace GreenshotPlugin.Core {
/// Rectangle
public static Rectangle FindAutoCropRectangle(Image image, int cropDifference) {
Rectangle cropRectangle = Rectangle.Empty;
- using (BitmapBuffer buffer = new BitmapBuffer((Bitmap)image, false)) {
- buffer.Lock();
- Rectangle currentRectangle = Rectangle.Empty;
- List checkPoints = new List();
- // Top Left
- checkPoints.Add(new Point(0, 0));
- // Bottom Left
- checkPoints.Add(new Point(0, image.Height-1));
- // Top Right
- checkPoints.Add(new Point(image.Width-1, 0));
- // Bottom Right
- checkPoints.Add( new Point(image.Width-1, image.Height-1));
+ Rectangle currentRectangle = Rectangle.Empty;
+ List checkPoints = new List();
+ // Top Left
+ checkPoints.Add(new Point(0, 0));
+ // Bottom Left
+ checkPoints.Add(new Point(0, image.Height - 1));
+ // Top Right
+ checkPoints.Add(new Point(image.Width - 1, 0));
+ // Bottom Right
+ checkPoints.Add(new Point(image.Width - 1, image.Height - 1));
+ using (IFastBitmap fastBitmap = FastBitmap.Create((Bitmap)image)) {
+ fastBitmap.Lock();
// find biggest area
foreach(Point checkPoint in checkPoints) {
- currentRectangle = FindAutoCropRectangle(buffer, checkPoint, cropDifference);
+ currentRectangle = FindAutoCropRectangle(fastBitmap, checkPoint, cropDifference);
if (currentRectangle.Width * currentRectangle.Height > cropRectangle.Width * cropRectangle.Height) {
cropRectangle = currentRectangle;
}
@@ -1344,7 +1344,7 @@ namespace GreenshotPlugin.Core {
if (!includeAlpha) {
toCount = toCount & 0xffffff;
}
- using (BitmapBuffer bb = new BitmapBuffer(sourceImage)) {
+ using (BitmapBuffer bb = new BitmapBuffer(sourceImage, false)) {
bb.Lock();
for (int y = 0; y < bb.Height; y++) {
for (int x = 0; x < bb.Width; x++) {
diff --git a/GreenshotPlugin/Core/QuantizerHelper.cs b/GreenshotPlugin/Core/QuantizerHelper.cs
index acb9ee10c..313388bc7 100644
--- a/GreenshotPlugin/Core/QuantizerHelper.cs
+++ b/GreenshotPlugin/Core/QuantizerHelper.cs
@@ -147,21 +147,13 @@ namespace GreenshotPlugin.Core {
}
// Use a bitmap to store the initial match, which is just as good as an array and saves us 2x the storage
- resultBitmap = new Bitmap(sourceBitmap.Width, sourceBitmap.Height, PixelFormat.Format8bppIndexed);
- resultBitmap.SetResolution(sourceBitmap.HorizontalResolution, sourceBitmap.VerticalResolution);
- bool is8Bit = sourceBitmap.PixelFormat == PixelFormat.Format8bppIndexed;
- using (BitmapBuffer bbbSrc = new BitmapBuffer(sourceBitmap, false)) {
- bbbSrc.Lock();
- using (BitmapBuffer bbbDest = new BitmapBuffer(resultBitmap, false)) {
- bbbDest.Lock();
- for (int y = 0; y < bbbSrc.Height; y++) {
- for (int x = 0; x < bbbSrc.Width; x++) {
- Color color;
- if (is8Bit) {
- color = bbbSrc.GetColor(x, y);
- } else {
- color = bbbSrc.GetColorAtWithoutAlpha(x, y);
- }
+ using (IFastBitmap sourceFastBitmap = FastBitmap.Create(sourceBitmap)) {
+ sourceFastBitmap.Lock();
+ using (FastChunkyBitmap destinationFastBitmap = FastBitmap.CreateEmpty(sourceBitmap.Size, PixelFormat.Format8bppIndexed, Color.White) as FastChunkyBitmap) {
+ destinationFastBitmap.Lock();
+ for (int y = 0; y < sourceFastBitmap.Height; y++) {
+ for (int x = 0; x < sourceFastBitmap.Width; x++) {
+ Color color = sourceFastBitmap.GetColorAt(x, y);
// To count the colors
int index = color.ToArgb() & 0x00ffffff;
// Check if we already have this color
@@ -183,9 +175,10 @@ namespace GreenshotPlugin.Core {
// Store the initial "match"
Int32 paletteIndex = (indexRed << 10) + (indexRed << 6) + indexRed + (indexGreen << 5) + indexGreen + indexBlue;
- bbbDest.SetColorIndexAt(x, y, (byte)(paletteIndex & 0xff));
+ destinationFastBitmap.SetColorIndexAt(x, y, (byte)(paletteIndex & 0xff));
}
}
+ resultBitmap = destinationFastBitmap.UnlockAndReturnBitmap();
}
}
}
@@ -204,20 +197,14 @@ namespace GreenshotPlugin.Core {
public Bitmap SimpleReindex() {
List colors = new List();
Dictionary lookup = new Dictionary();
- using (BitmapBuffer bbbDest = new BitmapBuffer(resultBitmap, false)) {
+ using (FastChunkyBitmap bbbDest = FastBitmap.Create(resultBitmap) as FastChunkyBitmap) {
bbbDest.Lock();
- using (BitmapBuffer bbbSrc = new BitmapBuffer(sourceBitmap, false)) {
+ using (IFastBitmap bbbSrc = FastBitmap.Create(sourceBitmap)) {
bbbSrc.Lock();
byte index;
- bool is8Bit = sourceBitmap.PixelFormat == PixelFormat.Format8bppIndexed;
for (int y = 0; y < bbbSrc.Height; y++) {
for (int x = 0; x < bbbSrc.Width; x++) {
- Color color;
- if (is8Bit) {
- color = bbbSrc.GetColor(x, y);
- } else {
- color = bbbSrc.GetColorAt(x, y);
- }
+ Color color = bbbSrc.GetColorAt(x, y);
if (lookup.ContainsKey(color)) {
index = lookup[color];
} else {
@@ -233,11 +220,12 @@ namespace GreenshotPlugin.Core {
// generates palette
ColorPalette imagePalette = resultBitmap.Palette;
+ Color[] entries = imagePalette.Entries;
for (Int32 paletteIndex = 0; paletteIndex < 256; paletteIndex++) {
if (paletteIndex < colorCount) {
- imagePalette.Entries[paletteIndex] = colors[paletteIndex];
+ entries[paletteIndex] = colors[paletteIndex];
} else {
- imagePalette.Entries[paletteIndex] = Color.Black;
+ entries[paletteIndex] = Color.Black;
}
}
resultBitmap.Palette = imagePalette;
@@ -324,22 +312,16 @@ namespace GreenshotPlugin.Core {
LOG.Info("Starting bitmap reconstruction...");
- using (BitmapBuffer bbbDest = new BitmapBuffer(resultBitmap, false)) {
+ using (FastChunkyBitmap bbbDest = FastBitmap.Create(resultBitmap) as FastChunkyBitmap) {
bbbDest.Lock();
- using (BitmapBuffer bbbSrc = new BitmapBuffer(sourceBitmap, false)) {
+ using (IFastBitmap bbbSrc = FastBitmap.Create(sourceBitmap)) {
bbbSrc.Lock();
Dictionary lookup = new Dictionary();
byte bestMatch;
- bool is8Bit = sourceBitmap.PixelFormat == PixelFormat.Format8bppIndexed;
for (int y = 0; y < bbbSrc.Height; y++) {
for (int x = 0; x < bbbSrc.Width; x++) {
- Color color;
- if (is8Bit) {
- color = bbbSrc.GetColor(x, y);
- } else {
- color = bbbSrc.GetColorAtWithoutAlpha(x, y);
- }
-
+ // Consider WithoutAlpha
+ Color color = bbbSrc.GetColorAt(x, y);
// No need to a strip the alpha as before
// Check if we already matched the color
@@ -386,6 +368,7 @@ namespace GreenshotPlugin.Core {
// generates palette
ColorPalette imagePalette = resultBitmap.Palette;
+ Color[] entries = imagePalette.Entries;
for (Int32 paletteIndex = 0; paletteIndex < allowedColorCount; paletteIndex++) {
if (sums[paletteIndex] > 0) {
reds[paletteIndex] /= sums[paletteIndex];
@@ -393,7 +376,7 @@ namespace GreenshotPlugin.Core {
blues[paletteIndex] /= sums[paletteIndex];
}
- imagePalette.Entries[paletteIndex] = Color.FromArgb(255, reds[paletteIndex], greens[paletteIndex], blues[paletteIndex]);
+ entries[paletteIndex] = Color.FromArgb(255, reds[paletteIndex], greens[paletteIndex], blues[paletteIndex]);
}
resultBitmap.Palette = imagePalette;