diff --git a/lime/graphics/utils/ImageDataUtil.hx b/lime/graphics/utils/ImageDataUtil.hx index c777e8c02..e0654a5e1 100644 --- a/lime/graphics/utils/ImageDataUtil.hx +++ b/lime/graphics/utils/ImageDataUtil.hx @@ -825,62 +825,71 @@ class ImageDataUtil { public static function setPixels (image:Image, rect:Rectangle, byteArray:ByteArray, format:PixelFormat):Void { - var len = Math.round (rect.width * rect.height); + if (image.buffer.data == null) return; - //#if (!js && !flash) - //if (rect.width == image.width && rect.height == image.height && rect.x == 0 && rect.y == 0) { - // - //image.buffer.data.buffer.blit (0, byteArray, 0, len * 4); - //return; - // - //} - //#end - - // TODO: optimize when rect is the same as the buffer size - - var data = image.buffer.data; - var offset = Math.round (image.buffer.width * (rect.y + image.offsetX) + (rect.x + image.offsetY)); - var pos = offset * 4; - var boundR = Math.round ((rect.x + rect.width + image.offsetX)); - var width = image.buffer.width; - var color; - - if (format == ARGB) { + #if ((cpp || neko) && !disable_cffi) + if (!System.disableCFFI) lime_image_data_util_set_pixels (image, rect, byteArray, format == ARGB ? 1 : 0); else + #end + { - for (i in 0...len) { + var len = Math.round (rect.width * rect.height); + + //#if (!js && !flash) + //if (rect.width == image.width && rect.height == image.height && rect.x == 0 && rect.y == 0) { + // + //image.buffer.data.buffer.blit (0, byteArray, 0, len * 4); + //return; + // + //} + //#end + + // TODO: optimize when rect is the same as the buffer size + + var data = image.buffer.data; + var offset = Math.round (image.buffer.width * (rect.y + image.offsetX) + (rect.x + image.offsetY)); + var pos = offset * 4; + var boundR = Math.round ((rect.x + rect.width + image.offsetX)); + var width = image.buffer.width; + var color; + + if (format == ARGB) { - if (((pos) % (width * 4)) >= boundR * 4) { + for (i in 0...len) { - pos += (width - boundR) * 4; + if (((pos) % (width * 4)) >= boundR * 4) { + + pos += (width - boundR) * 4; + + } + + color = byteArray.readUnsignedInt (); + + data[pos++] = (color & 0xFF0000) >>> 16; + data[pos++] = (color & 0x0000FF00) >>> 8; + data[pos++] = (color & 0x000000FF); + data[pos++] = (color & 0xFF000000) >>> 24; } - color = byteArray.readUnsignedInt (); + } else { - data[pos++] = (color & 0xFF0000) >>> 16; - data[pos++] = (color & 0x0000FF00) >>> 8; - data[pos++] = (color & 0x000000FF); - data[pos++] = (color & 0xFF000000) >>> 24; - - } - - } else { - - for (i in 0...len) { - - if (((pos) % (width * 4)) >= boundR * 4) { + for (i in 0...len) { - pos += (width - boundR) * 4; + if (((pos) % (width * 4)) >= boundR * 4) { + + pos += (width - boundR) * 4; + + } + + color = byteArray.readUnsignedInt (); + + data[pos++] = (color & 0xFF000000) >>> 24; + data[pos++] = (color & 0xFF0000) >>> 16; + data[pos++] = (color & 0x0000FF00) >>> 8; + data[pos++] = (color & 0x000000FF); } - color = byteArray.readUnsignedInt (); - - data[pos++] = (color & 0xFF000000) >>> 24; - data[pos++] = (color & 0xFF0000) >>> 16; - data[pos++] = (color & 0x0000FF00) >>> 8; - data[pos++] = (color & 0x000000FF); - } } @@ -946,6 +955,7 @@ class ImageDataUtil { private static var lime_image_data_util_merge = System.load ("lime", "lime_image_data_util_merge", -1); private static var lime_image_data_util_multiply_alpha = System.load ("lime", "lime_image_data_util_multiply_alpha", 1); private static var lime_image_data_util_resize = System.load ("lime", "lime_image_data_util_resize", 4); + private static var lime_image_data_util_set_pixels = System.load ("lime", "lime_image_data_util_set_pixels", 4); private static var lime_image_data_util_unmultiply_alpha = System.load ("lime", "lime_image_data_util_unmultiply_alpha", 1); #end diff --git a/project/include/graphics/utils/ImageDataUtil.h b/project/include/graphics/utils/ImageDataUtil.h index 1be0de46a..77ddaac6e 100644 --- a/project/include/graphics/utils/ImageDataUtil.h +++ b/project/include/graphics/utils/ImageDataUtil.h @@ -29,6 +29,7 @@ namespace lime { static void Merge (Image* image, Image* sourceImage, Rectangle* sourceRect, Vector2* destPoint, int redMultiplier, int greenMultiplier, int blueMultiplier, int alphaMultiplier); static void MultiplyAlpha (Image* image); static void Resize (Image* image, ImageBuffer* buffer, int width, int height); + static void SetPixels (Image* image, Rectangle* rect, ByteArray* bytes, PixelFormat format); static void UnmultiplyAlpha (Image* image); diff --git a/project/src/ExternalInterface.cpp b/project/src/ExternalInterface.cpp index 6a8e4223a..4d4b8a334 100644 --- a/project/src/ExternalInterface.cpp +++ b/project/src/ExternalInterface.cpp @@ -549,6 +549,18 @@ namespace lime { } + value lime_image_data_util_set_pixels (value image, value rect, value bytes, value format) { + + Image _image = Image (image); + Rectangle _rect = Rectangle (rect); + ByteArray _bytes = ByteArray (bytes); + PixelFormat _format = (PixelFormat)val_int (format); + ImageDataUtil::SetPixels (&_image, &_rect, &_bytes, _format); + return alloc_null (); + + } + + value lime_image_data_util_unmultiply_alpha (value image) { Image _image = Image (image); @@ -958,6 +970,7 @@ namespace lime { DEFINE_PRIM_MULT (lime_image_data_util_merge); DEFINE_PRIM (lime_image_data_util_multiply_alpha, 1); DEFINE_PRIM (lime_image_data_util_resize, 4); + DEFINE_PRIM (lime_image_data_util_set_pixels, 4); DEFINE_PRIM (lime_image_data_util_unmultiply_alpha, 1); DEFINE_PRIM (lime_image_encode, 3); DEFINE_PRIM (lime_image_load, 1); diff --git a/project/src/graphics/utils/ImageDataUtil.cpp b/project/src/graphics/utils/ImageDataUtil.cpp index fee50cb6d..13ff3e1ca 100644 --- a/project/src/graphics/utils/ImageDataUtil.cpp +++ b/project/src/graphics/utils/ImageDataUtil.cpp @@ -466,6 +466,69 @@ namespace lime { } + void ImageDataUtil::SetPixels (Image* image, Rectangle* rect, ByteArray* bytes, PixelFormat format) { + + int len = int (rect->width * rect->height); + + if (format == RGBA && rect->width == image->buffer->width && rect->height == image->buffer->height && rect->x == 0 && rect->y == 0) { + + memcpy (image->buffer->data->Bytes (), bytes->Bytes (), bytes->Size ()); + return; + + } + + uint8_t* data = (uint8_t*)image->buffer->data->Bytes (); + int* byteArray = (int*)bytes->Bytes (); + + int offset = int (image->buffer->width * (rect->y + image->offsetX) + (rect->x + image->offsetY)); + int pos = offset * 4; + int boundR = int ((rect->x + rect->width + image->offsetX)); + int width = image->buffer->width; + int color; + + if (format == ARGB) { + + for (int i = 0; i < len; i++) { + + if (((pos) % (width * 4)) >= boundR * 4) { + + pos += (width - boundR) * 4; + + } + + color = byteArray[i]; + + data[pos++] = (color >> 16) & 0xFF; + data[pos++] = (color >> 8) & 0xFF; + data[pos++] = color & 0xFF; + data[pos++] = (color >> 24) & 0xFF; + + } + + } else { + + for (int i = 0; i < len; i++) { + + if (((pos) % (width * 4)) >= boundR * 4) { + + pos += (width - boundR) * 4; + + } + + color = byteArray[i]; + + data[pos++] = (color >> 24) & 0xFF; + data[pos++] = (color >> 16) & 0xFF; + data[pos++] = (color >> 8) & 0xFF; + data[pos++] = color & 0xFF; + + } + + } + + } + + void ImageDataUtil::UnmultiplyAlpha (Image* image) { int length = image->buffer->data->Size () / 4;