diff --git a/lime/graphics/utils/ImageDataUtil.hx b/lime/graphics/utils/ImageDataUtil.hx index 028f70e85..ce4f36b32 100644 --- a/lime/graphics/utils/ImageDataUtil.hx +++ b/lime/graphics/utils/ImageDataUtil.hx @@ -28,9 +28,9 @@ class ImageDataUtil { var data = image.buffer.data; if (data == null) return; - //#if ((cpp || neko) && !disable_cffi) - //if (!System.disableCFFI) lime_image_data_util_color_transform (image, rect, colorMatrix); else - //#end + #if ((cpp || neko) && !disable_cffi) + if (!System.disableCFFI) lime_image_data_util_color_transform (image, rect, colorMatrix); else + #end { var format = image.buffer.format; @@ -215,10 +215,18 @@ class ImageDataUtil { oneMinusSourceAlpha = 1 - sourceAlpha; blendAlpha = sourceAlpha + (destAlpha * oneMinusSourceAlpha); - destPixel.r = RGBA.__clamp[Math.round ((sourcePixel.r * sourceAlpha + destPixel.r * destAlpha * oneMinusSourceAlpha) / blendAlpha)]; - destPixel.g = RGBA.__clamp[Math.round ((sourcePixel.g * sourceAlpha + destPixel.g * destAlpha * oneMinusSourceAlpha) / blendAlpha)]; - destPixel.b = RGBA.__clamp[Math.round ((sourcePixel.b * sourceAlpha + destPixel.b * destAlpha * oneMinusSourceAlpha) / blendAlpha)]; - destPixel.a = RGBA.__clamp[Math.round (blendAlpha * 255.0)]; + if (blendAlpha == 0) { + + destPixel = 0; + + } else { + + destPixel.r = RGBA.__clamp[Math.round ((sourcePixel.r * sourceAlpha + destPixel.r * destAlpha * oneMinusSourceAlpha) / blendAlpha)]; + destPixel.g = RGBA.__clamp[Math.round ((sourcePixel.g * sourceAlpha + destPixel.g * destAlpha * oneMinusSourceAlpha) / blendAlpha)]; + destPixel.b = RGBA.__clamp[Math.round ((sourcePixel.b * sourceAlpha + destPixel.b * destAlpha * oneMinusSourceAlpha) / blendAlpha)]; + destPixel.a = RGBA.__clamp[Math.round (blendAlpha * 255.0)]; + + } destPixel.writeUInt8 (destData, destPosition, destFormat, destPremultiplied); diff --git a/lime/math/Rectangle.hx b/lime/math/Rectangle.hx index d6a39485d..365687837 100644 --- a/lime/math/Rectangle.hx +++ b/lime/math/Rectangle.hx @@ -250,8 +250,8 @@ class Rectangle { } - var cacheRight = right; - var cacheBottom = bottom; + //var cacheRight = right; + //var cacheBottom = bottom; if (this.x < x) this.x = x; if (this.y < y) this.y = y; diff --git a/lime/math/color/ARGB.hx b/lime/math/color/ARGB.hx index f1ffbfcf6..dcbd16abd 100644 --- a/lime/math/color/ARGB.hx +++ b/lime/math/color/ARGB.hx @@ -34,6 +34,22 @@ abstract ARGB(Int) from Int to Int { } + public inline function multiplyAlpha () { + + if (a == 0) { + + this = 0; + + } else if (a != 0xFF) { + + a16 = RGBA.__alpha16[a]; + set (a, (r * a16) >> 16, (g * a16) >> 16, (b * a16) >> 16); + + } + + } + + public inline function readUInt8 (data:UInt8Array, offset:Int, format:PixelFormat = RGBA32, premultiplied:Bool = false):Void { switch (format) { @@ -61,17 +77,16 @@ abstract ARGB(Int) from Int to Int { } - public inline function multiplyAlpha () { + public inline function set (a:Int, r:Int, g:Int, b:Int):Void { - a16 = RGBA.__alpha16[a]; - set (a, (r * a16) >> 16, (g * a16) >> 16, (b * a16) >> 16); + this = ((a & 0xFF) << 24) | ((r & 0xFF) << 16) | ((g & 0xFF) << 8) | (b & 0xFF); } public inline function unmultiplyAlpha () { - if (a != 0) { + if (a != 0 && a != 0xFF) { unmult = 255.0 / a; set (a, RGBA.__clamp[Math.floor (r * unmult)], RGBA.__clamp[Math.floor (g * unmult)], RGBA.__clamp[Math.floor (b * unmult)]); @@ -81,13 +96,6 @@ abstract ARGB(Int) from Int to Int { } - public inline function set (a:Int, r:Int, g:Int, b:Int):Void { - - this = ((a & 0xFF) << 24) | ((r & 0xFF) << 16) | ((g & 0xFF) << 8) | (b & 0xFF); - - } - - public inline function writeUInt8 (data:UInt8Array, offset:Int, format:PixelFormat = RGBA32, premultiplied:Bool = false):Void { if (premultiplied) { diff --git a/lime/math/color/BGRA.hx b/lime/math/color/BGRA.hx index f644f7101..7bba30d32 100644 --- a/lime/math/color/BGRA.hx +++ b/lime/math/color/BGRA.hx @@ -34,6 +34,22 @@ abstract BGRA(Int) from Int to Int { } + public inline function multiplyAlpha () { + + if (a == 0) { + + this = 0; + + } else if (a != 0xFF) { + + a16 = RGBA.__alpha16[a]; + set ((b * a16) >> 16, (g * a16) >> 16, (r * a16) >> 16, a); + + } + + } + + public inline function readUInt8 (data:UInt8Array, offset:Int, format:PixelFormat = RGBA32, premultiplied:Bool = false):Void { switch (format) { @@ -61,17 +77,16 @@ abstract BGRA(Int) from Int to Int { } - public inline function multiplyAlpha () { + public inline function set (b:Int, g:Int, r:Int, a:Int):Void { - a16 = RGBA.__alpha16[a]; - set ((b * a16) >> 16, (g * a16) >> 16, (r * a16) >> 16, a); + this = ((b & 0xFF) << 24) | ((g & 0xFF) << 16) | ((r & 0xFF) << 8) | (a & 0xFF); } public inline function unmultiplyAlpha () { - if (a != 0) { + if (a != 0 && a != 0xFF) { unmult = 255.0 / a; set (RGBA.__clamp[Math.floor (b * unmult)], RGBA.__clamp[Math.floor (g * unmult)], RGBA.__clamp[Math.floor (r * unmult)], a); @@ -81,13 +96,6 @@ abstract BGRA(Int) from Int to Int { } - public inline function set (b:Int, g:Int, r:Int, a:Int):Void { - - this = ((b & 0xFF) << 24) | ((g & 0xFF) << 16) | ((r & 0xFF) << 8) | (a & 0xFF); - - } - - public inline function writeUInt8 (data:UInt8Array, offset:Int, format:PixelFormat = RGBA32, premultiplied:Bool = false):Void { if (premultiplied) { diff --git a/lime/math/color/RGBA.hx b/lime/math/color/RGBA.hx index b3e0c83e3..e86f73b5a 100644 --- a/lime/math/color/RGBA.hx +++ b/lime/math/color/RGBA.hx @@ -65,6 +65,26 @@ abstract RGBA(Int) from Int to Int { } + public inline function multiplyAlpha () { + + if (a == 0) { + + if (this != 0) { + + this = 0; + + } + + } else if (a != 0xFF) { + + a16 = __alpha16[a]; + set ((r * a16) >> 16, (g * a16) >> 16, (b * a16) >> 16, a); + + } + + } + + public inline function readUInt8 (data:UInt8Array, offset:Int, format:PixelFormat = RGBA32, premultiplied:Bool = false):Void { switch (format) { @@ -92,17 +112,16 @@ abstract RGBA(Int) from Int to Int { } - public inline function multiplyAlpha () { + public inline function set (r:Int, g:Int, b:Int, a:Int):Void { - a16 = __alpha16[a]; - set ((r * a16) >> 16, (g * a16) >> 16, (b * a16) >> 16, a); + this = ((r & 0xFF) << 24) | ((g & 0xFF) << 16) | ((b & 0xFF) << 8) | (a & 0xFF); } public inline function unmultiplyAlpha () { - if (a != 0) { + if (a != 0 && a != 0xFF) { unmult = 255.0 / a; set (__clamp[Math.floor (r * unmult)], __clamp[Math.floor (g * unmult)], __clamp[Math.floor (b * unmult)], a); @@ -112,13 +131,6 @@ abstract RGBA(Int) from Int to Int { } - public inline function set (r:Int, g:Int, b:Int, a:Int):Void { - - this = ((r & 0xFF) << 24) | ((g & 0xFF) << 16) | ((b & 0xFF) << 8) | (a & 0xFF); - - } - - public inline function writeUInt8 (data:UInt8Array, offset:Int, format:PixelFormat = RGBA32, premultiplied:Bool = false):Void { if (premultiplied) { diff --git a/project/include/graphics/ImageBuffer.h b/project/include/graphics/ImageBuffer.h index 91f01489c..3dbf4fc52 100644 --- a/project/include/graphics/ImageBuffer.h +++ b/project/include/graphics/ImageBuffer.h @@ -28,8 +28,9 @@ namespace lime { Bytes *data; PixelFormat format; int height; - int width; + bool premultiplied; bool transparent; + int width; private: diff --git a/project/include/graphics/PixelFormat.h b/project/include/graphics/PixelFormat.h index fb35c7cb1..328f410bb 100644 --- a/project/include/graphics/PixelFormat.h +++ b/project/include/graphics/PixelFormat.h @@ -7,9 +7,9 @@ namespace lime { enum PixelFormat { - RGBA, - ARGB, - BGRA + RGBA32, + ARGB32, + BGRA32 }; diff --git a/project/include/graphics/utils/ImageDataUtil.h b/project/include/graphics/utils/ImageDataUtil.h index 02e1e86fc..e67ec5299 100644 --- a/project/include/graphics/utils/ImageDataUtil.h +++ b/project/include/graphics/utils/ImageDataUtil.h @@ -37,6 +37,32 @@ namespace lime { }; + class ImageDataView { + + + public: + + ImageDataView (Image* image, Rectangle* rect); + + void Clip (int x, int y, int width, int height); + int Row (int y); + + int x; + int y; + int width; + int height; + + private: + + Image* image; + int offset; + Rectangle* rect; + int stride; + + + }; + + } diff --git a/project/include/math/ColorMatrix.h b/project/include/math/ColorMatrix.h index 8d3b80fc8..1de6c652b 100644 --- a/project/include/math/ColorMatrix.h +++ b/project/include/math/ColorMatrix.h @@ -4,6 +4,7 @@ #include #include +#include namespace lime { @@ -20,16 +21,24 @@ namespace lime { float GetAlphaMultiplier (); float GetAlphaOffset (); + void GetAlphaTable (unsigned char* table); float GetBlueMultiplier (); float GetBlueOffset (); - int GetColor (); + void GetBlueTable (unsigned char* table); + int32_t GetColor (); float GetGreenMultiplier (); float GetGreenOffset (); + void GetGreenTable (unsigned char* table); float GetRedMultiplier (); float GetRedOffset (); + void GetRedTable (unsigned char* table); float data[20]; + private: + + void GetDataTable (unsigned char* table, float multiplier, float offset); + }; diff --git a/project/include/math/Rectangle.h b/project/include/math/Rectangle.h index a6b94f9e2..5c3cbf84d 100644 --- a/project/include/math/Rectangle.h +++ b/project/include/math/Rectangle.h @@ -17,6 +17,8 @@ namespace lime { Rectangle (double x, double y, double width, double height); Rectangle (value rect); + void Contract (double x, double y, double width, double height); + double height; double width; double x; diff --git a/project/include/math/color/ARGB.h b/project/include/math/color/ARGB.h new file mode 100644 index 000000000..8d3b80fc8 --- /dev/null +++ b/project/include/math/color/ARGB.h @@ -0,0 +1,40 @@ +#ifndef LIME_MATH_COLOR_MATRIX_H +#define LIME_MATH_COLOR_MATRIX_H + + +#include +#include + + +namespace lime { + + + class ColorMatrix { + + + public: + + ColorMatrix (); + ColorMatrix (value colorMatrix); + ~ColorMatrix (); + + float GetAlphaMultiplier (); + float GetAlphaOffset (); + float GetBlueMultiplier (); + float GetBlueOffset (); + int GetColor (); + float GetGreenMultiplier (); + float GetGreenOffset (); + float GetRedMultiplier (); + float GetRedOffset (); + + float data[20]; + + + }; + + +} + + +#endif \ No newline at end of file diff --git a/project/include/math/color/BGRA.h b/project/include/math/color/BGRA.h new file mode 100644 index 000000000..8d3b80fc8 --- /dev/null +++ b/project/include/math/color/BGRA.h @@ -0,0 +1,40 @@ +#ifndef LIME_MATH_COLOR_MATRIX_H +#define LIME_MATH_COLOR_MATRIX_H + + +#include +#include + + +namespace lime { + + + class ColorMatrix { + + + public: + + ColorMatrix (); + ColorMatrix (value colorMatrix); + ~ColorMatrix (); + + float GetAlphaMultiplier (); + float GetAlphaOffset (); + float GetBlueMultiplier (); + float GetBlueOffset (); + int GetColor (); + float GetGreenMultiplier (); + float GetGreenOffset (); + float GetRedMultiplier (); + float GetRedOffset (); + + float data[20]; + + + }; + + +} + + +#endif \ No newline at end of file diff --git a/project/include/math/color/RGBA.h b/project/include/math/color/RGBA.h new file mode 100644 index 000000000..fc96ccee3 --- /dev/null +++ b/project/include/math/color/RGBA.h @@ -0,0 +1,204 @@ +#ifndef LIME_MATH_COLOR_RGBA_H +#define LIME_MATH_COLOR_RGBA_H + + +#include +#include + + +namespace lime { + + + int __alpha16[0xFF + 1]; + int __clamp[0xFF + 0xFF + 1]; + static int a16; + static double unmult; + + int initValues () { + + for (int i = 0; i < 256; i++) { + + // Seem to need +1 to get the same results as Haxe in multiplyAlpha + __alpha16[i] = (i + 1) * ((1 << 16) / 0xFF); + + } + + for (int i = 0; i < 0xFF; i++) { + + __clamp[i] = i; + + } + + for (int i = 0xFF; i < (0xFF + 0xFF + 1); i++) { + + __clamp[i] = 0xFF; + + } + + return 0; + + } + + static int initValues_ = initValues (); + + + struct RGBA { + + + public: + + inline RGBA () { + + r = 0; + g = 0; + b = 0; + a = 0; + + } + + + inline RGBA (int32_t rgba) { + + r = (rgba >> 24) & 0xFF; + g = (rgba >> 16) & 0xFF; + b = (rgba >> 8) & 0xFF; + a = rgba & 0xFF; + + } + + + inline RGBA (unsigned char r, unsigned char g, unsigned char b, unsigned char a) { + + Set (r, g, b, a); + + } + + + inline int32_t Get () { + + int32_t value = ((r & 0xFF) << 24) | ((g & 0xFF) << 16) | ((b & 0xFF) << 8) | (a & 0xFF); + return value; + + } + + + inline void MultiplyAlpha () { + + if (a == 0) { + + Set (0, 0, 0, 0); + + } else if (a != 0xFF) { + + a16 = __alpha16[a]; + Set ((r * a16) >> 16, (g * a16) >> 16, (b * a16) >> 16, a); + + } + + } + + + inline void UnmultiplyAlpha () { + + if (a != 0 && a != 0xFF) { + + unmult = 255.0 / a; + Set (__clamp[(int)(r * unmult)], __clamp[(int)(g * unmult)], __clamp[(int)(b * unmult)], a); + + } + + } + + + inline void ReadUInt8 (const unsigned char* data, int offset, PixelFormat format, bool premultiplied) { + + switch (format) { + + case BGRA32: + + Set (data[offset + 2], data[offset + 1], data[offset], data[offset + 3]); + break; + + case RGBA32: + + Set (data[offset], data[offset + 1], data[offset + 2], data[offset + 3]); + break; + + case ARGB32: + + Set (data[offset + 1], data[offset + 2], data[offset + 3], data[offset]); + break; + + } + + if (premultiplied) { + + UnmultiplyAlpha (); + + } + + } + + + inline void Set (unsigned char r, unsigned char g, unsigned char b, unsigned char a) { + + this->r = r; + this->g = g; + this->b = b; + this->a = a; + + } + + + inline void WriteUInt8 (unsigned char* data, int offset, PixelFormat format, bool premultiplied) { + + if (premultiplied) { + + MultiplyAlpha (); + + } + + switch (format) { + + case BGRA32: + + data[offset] = b; + data[offset + 1] = g; + data[offset + 2] = r; + data[offset + 3] = a; + break; + + case RGBA32: + + data[offset] = r; + data[offset + 1] = g; + data[offset + 2] = b; + data[offset + 3] = a; + break; + + case ARGB32: + + data[offset] = a; + data[offset + 1] = r; + data[offset + 2] = g; + data[offset + 3] = b; + break; + + } + + } + + + unsigned char r; + unsigned char g; + unsigned char b; + unsigned char a; + + + }; + + +} + + +#endif \ No newline at end of file diff --git a/project/src/graphics/ImageBuffer.cpp b/project/src/graphics/ImageBuffer.cpp index d6c669c4b..4129d06fa 100644 --- a/project/src/graphics/ImageBuffer.cpp +++ b/project/src/graphics/ImageBuffer.cpp @@ -9,8 +9,9 @@ namespace lime { static int id_data; static int id_format; static int id_height; - static int id_width; + static int id_premultiplied; static int id_transparent; + static int id_width; static bool init = false; @@ -19,8 +20,9 @@ namespace lime { width = 0; height = 0; bitsPerPixel = 32; - format = RGBA; + format = RGBA32; data = 0; + premultiplied = false; transparent = false; } @@ -37,6 +39,7 @@ namespace lime { id_height = val_id ("height"); id_data = val_id ("data"); id_format = val_id ("format"); + id_premultiplied = val_id ("premultiplied"); init = true; } @@ -48,6 +51,7 @@ namespace lime { transparent = val_bool (val_field (imageBuffer, id_transparent)); value data_value = val_field (imageBuffer, id_data); value buffer_value = val_field (data_value, id_buffer); + premultiplied = val_bool (val_field (imageBuffer, id_premultiplied)); data = new Bytes (buffer_value); } @@ -119,6 +123,7 @@ namespace lime { id_height = val_id ("height"); id_data = val_id ("data"); id_format = val_id ("format"); + id_premultiplied = val_id ("premultiplied"); init = true; } @@ -130,6 +135,7 @@ namespace lime { alloc_field (mValue, id_data, data ? data->Value () : alloc_null ()); alloc_field (mValue, id_transparent, alloc_bool (transparent)); alloc_field (mValue, id_format, alloc_int (format)); + alloc_field (mValue, id_premultiplied, alloc_bool (premultiplied)); return mValue; } diff --git a/project/src/graphics/utils/ImageDataUtil.cpp b/project/src/graphics/utils/ImageDataUtil.cpp index 3636e1488..41427ecb7 100644 --- a/project/src/graphics/utils/ImageDataUtil.cpp +++ b/project/src/graphics/utils/ImageDataUtil.cpp @@ -1,4 +1,5 @@ #include +#include #include #include @@ -6,77 +7,39 @@ namespace lime { - static int __alpha16[0xFF + 1]; - static int __clamp[0xFF + 0xFF + 1]; - - int initValues () { - - for (int i = 0; i < 256; i++) { - - // Seem to need +1 to get the same results as Haxe in multiplyAlpha - __alpha16[i] = (i + 1) * ((1 << 16) / 0xFF); - - } - - for (int i = 0; i < 0xFF; i++) { - - __clamp[i] = i; - - } - - for (int i = 0xFF; i < (0xFF + 0xFF + 1); i++) { - - __clamp[i] = 0xFF; - - } - - return 0; - - } - - static int initValues_ = initValues (); - - void ImageDataUtil::ColorTransform (Image* image, Rectangle* rect, ColorMatrix* colorMatrix) { - int stride = image->buffer->Stride (); - int offset; - - int rowStart = int (rect->y + image->offsetY); - int rowEnd = int (rect->y + rect->height + image->offsetY); - int columnStart = int (rect->x + image->offsetX); - int columnEnd = int (rect->x + rect->width + image->offsetX); - + PixelFormat format = image->buffer->format; + bool premultiplied = image->buffer->premultiplied; uint8_t* data = (uint8_t*)image->buffer->data->Data (); - int r, g, b, a, ex = 0; - float alphaMultiplier = colorMatrix->GetAlphaMultiplier (); - float redMultiplier = colorMatrix->GetRedMultiplier (); - float greenMultiplier = colorMatrix->GetGreenMultiplier (); - float blueMultiplier = colorMatrix->GetBlueMultiplier (); - int alphaOffset = colorMatrix->GetAlphaOffset (); - int redOffset = colorMatrix->GetRedOffset (); - int greenOffset = colorMatrix->GetGreenOffset (); - int blueOffset = colorMatrix->GetBlueOffset (); + ImageDataView dataView = ImageDataView (image, rect); - for (int row = rowStart; row < rowEnd; row++) { + unsigned char alphaTable[256]; + unsigned char redTable[256]; + unsigned char greenTable[256]; + unsigned char blueTable[256]; + + colorMatrix->GetAlphaTable (alphaTable); + colorMatrix->GetRedTable (redTable); + colorMatrix->GetGreenTable (greenTable); + colorMatrix->GetBlueTable (blueTable); + + int row; + int offset; + RGBA pixel; + + for (int y = 0; y < dataView.height; y++) { - for (int column = columnStart; column < columnEnd; column++) { + row = dataView.Row (y); + + for (int x = 0; x < dataView.width; x++) { - offset = (row * stride) + (column * 4); + offset = row + (x * 4); - a = (data[offset + 3] * alphaMultiplier) + alphaOffset; - ex = a > 0xFF ? a - 0xFF : 0; - b = (data[offset + 2] * blueMultiplier) + blueOffset + ex; - ex = b > 0xFF ? b - 0xFF : 0; - g = (data[offset + 1] * greenMultiplier) + greenOffset + ex; - ex = g > 0xFF ? g - 0xFF : 0; - r = (data[offset] * redMultiplier) + redOffset + ex; - - data[offset] = r > 0xFF ? 0xFF : r; - data[offset + 1] = g > 0xFF ? 0xFF : g; - data[offset + 2] = b > 0xFF ? 0xFF : b; - data[offset + 3] = a > 0xFF ? 0xFF : a; + pixel.ReadUInt8 (data, offset, format, premultiplied); + pixel.Set (redTable[pixel.r], greenTable[pixel.g], blueTable[pixel.b], alphaTable[pixel.a]); + pixel.WriteUInt8 (data, offset, format, premultiplied); } @@ -336,7 +299,7 @@ namespace lime { int length = int (rect->width * rect->height); pixels->Resize (length * 4); - if (format == RGBA && rect->width == image->buffer->width && rect->height == image->buffer->height && rect->x == 0 && rect->y == 0) { + if (format == RGBA32 && rect->width == image->buffer->width && rect->height == image->buffer->height && rect->x == 0 && rect->y == 0) { memcpy (pixels->Data (), image->buffer->data->Data (), image->buffer->data->Length ()); return; @@ -351,7 +314,7 @@ namespace lime { int srcRowOffset = srcStride - int (4 * rect->width); int srcRowEnd = int (4 * (rect->x + rect->width)); - if (format == ARGB) { + if (format == ARGB32) { for (int i = 0; i < length; i++) { @@ -510,7 +473,7 @@ namespace lime { switch (image->buffer->format) { - case RGBA: + case RGBA32: r1 = 0; g1 = 1; @@ -518,7 +481,7 @@ namespace lime { a1 = 3; break; - case ARGB: + case ARGB32: r1 = 1; g1 = 2; @@ -526,7 +489,7 @@ namespace lime { a1 = 0; break; - case BGRA: + case BGRA32: r1 = 2; g1 = 1; @@ -538,7 +501,7 @@ namespace lime { switch (format) { - case RGBA: + case RGBA32: r2 = 0; g2 = 1; @@ -546,7 +509,7 @@ namespace lime { a2 = 3; break; - case ARGB: + case ARGB32: r2 = 1; g2 = 2; @@ -554,7 +517,7 @@ namespace lime { a2 = 0; break; - case BGRA: + case BGRA32: r2 = 2; g2 = 1; @@ -587,7 +550,7 @@ namespace lime { void ImageDataUtil::SetPixels (Image* image, Rectangle* rect, Bytes* bytes, PixelFormat format) { - if (format == RGBA && rect->width == image->buffer->width && rect->height == image->buffer->height && rect->x == 0 && rect->y == 0) { + if (format == RGBA32 && rect->width == image->buffer->width && rect->height == image->buffer->height && rect->x == 0 && rect->y == 0) { memcpy (image->buffer->data->Data (), bytes->Data (), bytes->Length ()); return; @@ -599,7 +562,7 @@ namespace lime { int width = image->buffer->width; int color; - if (format == ARGB) { + if (format == ARGB32) { int pos = offset * 4; int len = int (rect->width * rect->height * 4); @@ -676,4 +639,49 @@ namespace lime { } + ImageDataView::ImageDataView (Image* image, Rectangle* rect) { + + this->image = image; + + if (rect->x < 0) rect->x = 0; + if (rect->y < 0) rect->y = 0; + if (rect->x + rect->width > image->width) rect->width = image->width - rect->x; + if (rect->y + rect->height > image->height) rect->height = image->height - rect->y; + if (rect->width < 0) rect->width = 0; + if (rect->height < 0) rect->height = 0; + this->rect = rect; + + stride = image->buffer->Stride (); + + x = ceil (this->rect->x); + y = ceil (this->rect->y); + width = floor (this->rect->width); + height = floor (this->rect->height); + offset = (stride * (this->y + image->offsetY)) + ((this->x + image->offsetX) * 4); + + + } + + + void ImageDataView::Clip (int x, int y, int width, int height) { + + rect->Contract (x, y, width, height); + + this->x = ceil (rect->x); + this->y = ceil (rect->y); + this->width = floor (rect->width); + this->height = floor (rect->height); + offset = (stride * (this->y + image->offsetY)) + ((this->x + image->offsetX) * 4); + + + } + + + inline int ImageDataView::Row (int y) { + + return offset + stride * y; + + } + + } \ No newline at end of file diff --git a/project/src/math/ColorMatrix.cpp b/project/src/math/ColorMatrix.cpp index 34263b3ae..40b4a8725 100644 --- a/project/src/math/ColorMatrix.cpp +++ b/project/src/math/ColorMatrix.cpp @@ -57,67 +57,111 @@ namespace lime { } - float ColorMatrix::GetAlphaMultiplier () { + float inline ColorMatrix::GetAlphaMultiplier () { return data[18]; } - float ColorMatrix::GetAlphaOffset () { + float inline ColorMatrix::GetAlphaOffset () { return data[19] * 255; } - float ColorMatrix::GetBlueMultiplier () { + void ColorMatrix::GetAlphaTable (unsigned char* table) { + + GetDataTable (table, GetAlphaMultiplier (), GetAlphaOffset ()); + + } + + + float inline ColorMatrix::GetBlueMultiplier () { return data[12]; } - float ColorMatrix::GetBlueOffset () { + float inline ColorMatrix::GetBlueOffset () { return data[14] * 255; } - int ColorMatrix::GetColor () { + void ColorMatrix::GetBlueTable (unsigned char* table) { + + GetDataTable (table, GetBlueMultiplier (), GetBlueOffset ()); + + } + + + int32_t inline ColorMatrix::GetColor () { return ((int (GetRedOffset ()) << 16) | (int (GetGreenOffset ()) << 8) | int (GetBlueOffset ())); } - float ColorMatrix::GetGreenMultiplier () { + void inline ColorMatrix::GetDataTable (unsigned char* table, float multiplier, float offset) { + + int32_t value; + + for (int i = 0; i < 256; i++) { + + value = floor (i * multiplier + offset); + if (value > 0xFF) value = 0xFF; + if (value < 0) value = 0; + table[i] = value; + + } + + } + + + float inline ColorMatrix::GetGreenMultiplier () { return data[6]; } - float ColorMatrix::GetGreenOffset () { + float inline ColorMatrix::GetGreenOffset () { return data[9] * 255; } - float ColorMatrix::GetRedMultiplier () { + void ColorMatrix::GetGreenTable (unsigned char* table) { + + GetDataTable (table, GetGreenMultiplier (), GetGreenOffset ()); + + } + + + float inline ColorMatrix::GetRedMultiplier () { return data[0]; } - float ColorMatrix::GetRedOffset () { + float inline ColorMatrix::GetRedOffset () { return data[4] * 255; } + void ColorMatrix::GetRedTable (unsigned char* table) { + + GetDataTable (table, GetRedMultiplier (), GetRedOffset ()); + + } + + } \ No newline at end of file diff --git a/project/src/math/Rectangle.cpp b/project/src/math/Rectangle.cpp index dcdc0c5bf..0ce21c467 100644 --- a/project/src/math/Rectangle.cpp +++ b/project/src/math/Rectangle.cpp @@ -51,4 +51,23 @@ namespace lime { } + void Rectangle::Contract (double x, double y, double width, double height) { + + if (this->width == 0 && this->height == 0) { + + return; + + } + + //double cacheRight = this->x + this->width; + //double cacheBottom = this->y + this->height; + + if (this->x < x) this->x = x; + if (this->y < y) this->y = y; + if (this->x + this->width > x + width) this->width = x + width - this->x; + if (this->y + this->height > y + height) this->height = y + height - this->y; + + } + + } \ No newline at end of file