Add more Image pixel operation CFFI functions
This commit is contained in:
@@ -165,8 +165,11 @@
|
||||
<file name="src/audio/format/WAV.cpp" />
|
||||
<file name="src/audio/AudioBuffer.cpp" />
|
||||
<file name="src/graphics/utils/ImageDataUtil.cpp" />
|
||||
<file name="src/graphics/Image.cpp" />
|
||||
<file name="src/graphics/ImageBuffer.cpp" />
|
||||
<file name="src/graphics/RenderEvent.cpp" />
|
||||
<file name="src/math/ColorMatrix.cpp" />
|
||||
<file name="src/math/Rectangle.cpp" />
|
||||
<file name="src/ui/GamepadEvent.cpp" />
|
||||
<file name="src/ui/KeyEvent.cpp" />
|
||||
<file name="src/ui/MouseEvent.cpp" />
|
||||
|
||||
39
project/include/graphics/Image.h
Normal file
39
project/include/graphics/Image.h
Normal file
@@ -0,0 +1,39 @@
|
||||
#ifndef LIME_GRAPHICS_IMAGE_H
|
||||
#define LIME_GRAPHICS_IMAGE_H
|
||||
|
||||
|
||||
#include <hx/CFFI.h>
|
||||
#include <graphics/ImageBuffer.h>
|
||||
#include <utils/ByteArray.h>
|
||||
|
||||
|
||||
namespace lime {
|
||||
|
||||
|
||||
class Image {
|
||||
|
||||
|
||||
public:
|
||||
|
||||
Image ();
|
||||
Image (value image);
|
||||
~Image ();
|
||||
|
||||
ImageBuffer *buffer;
|
||||
int height;
|
||||
int offsetX;
|
||||
int offsetY;
|
||||
int width;
|
||||
|
||||
private:
|
||||
|
||||
value mValue;
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
@@ -3,7 +3,9 @@
|
||||
|
||||
|
||||
#include <hx/CFFI.h>
|
||||
#include <utils/ByteArray.h>
|
||||
#include <graphics/Image.h>
|
||||
#include <math/ColorMatrix.h>
|
||||
#include <math/Rectangle.h>
|
||||
|
||||
|
||||
namespace lime {
|
||||
@@ -14,8 +16,9 @@ namespace lime {
|
||||
|
||||
public:
|
||||
|
||||
static void MultiplyAlpha (ByteArray *bytes);
|
||||
static void UnmultiplyAlpha (ByteArray *bytes);
|
||||
static void ColorTransform (Image *image, Rectangle *rect, ColorMatrix *ColorMatrix);
|
||||
static void MultiplyAlpha (Image *image);
|
||||
static void UnmultiplyAlpha (Image *image);
|
||||
|
||||
|
||||
};
|
||||
|
||||
40
project/include/math/ColorMatrix.h
Normal file
40
project/include/math/ColorMatrix.h
Normal file
@@ -0,0 +1,40 @@
|
||||
#ifndef LIME_MATH_COLOR_MATRIX_H
|
||||
#define LIME_MATH_COLOR_MATRIX_H
|
||||
|
||||
|
||||
#include <hx/CFFI.h>
|
||||
#include <system/System.h>
|
||||
|
||||
|
||||
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
|
||||
31
project/include/math/Rectangle.h
Normal file
31
project/include/math/Rectangle.h
Normal file
@@ -0,0 +1,31 @@
|
||||
#ifndef LIME_MATH_RECTANGLE_H
|
||||
#define LIME_MATH_RECTANGLE_H
|
||||
|
||||
|
||||
#include <hx/CFFI.h>
|
||||
|
||||
|
||||
namespace lime {
|
||||
|
||||
|
||||
class Rectangle {
|
||||
|
||||
|
||||
public:
|
||||
|
||||
Rectangle ();
|
||||
Rectangle (value _rect);
|
||||
|
||||
double height;
|
||||
double width;
|
||||
double x;
|
||||
double y;
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
@@ -16,6 +16,7 @@
|
||||
#include <graphics/format/JPEG.h>
|
||||
#include <graphics/format/PNG.h>
|
||||
#include <graphics/utils/ImageDataUtil.h>
|
||||
#include <graphics/Image.h>
|
||||
#include <graphics/ImageBuffer.h>
|
||||
#include <graphics/Renderer.h>
|
||||
#include <graphics/RenderEvent.h>
|
||||
@@ -369,15 +370,6 @@ namespace lime {
|
||||
}
|
||||
|
||||
|
||||
value lime_image_data_util_multiply_alpha (value data) {
|
||||
|
||||
ByteArray bytes = ByteArray (data);
|
||||
ImageDataUtil::MultiplyAlpha (&bytes);
|
||||
return alloc_null ();
|
||||
|
||||
}
|
||||
|
||||
|
||||
value lime_image_encode (value buffer, value type, value quality) {
|
||||
|
||||
ImageBuffer imageBuffer = ImageBuffer (buffer);
|
||||
@@ -456,6 +448,35 @@ namespace lime {
|
||||
}
|
||||
|
||||
|
||||
value lime_image_data_util_color_transform (value image, value rect, value colorMatrix) {
|
||||
|
||||
Image _image = Image (image);
|
||||
Rectangle _rect = Rectangle (rect);
|
||||
ColorMatrix _colorMatrix = ColorMatrix (colorMatrix);
|
||||
ImageDataUtil::ColorTransform (&_image, &_rect, &_colorMatrix);
|
||||
return alloc_null ();
|
||||
|
||||
}
|
||||
|
||||
|
||||
value lime_image_data_util_multiply_alpha (value image) {
|
||||
|
||||
Image _image = Image (image);
|
||||
ImageDataUtil::MultiplyAlpha (&_image);
|
||||
return alloc_null ();
|
||||
|
||||
}
|
||||
|
||||
|
||||
value lime_image_data_util_unmultiply_alpha (value image) {
|
||||
|
||||
Image _image = Image (image);
|
||||
ImageDataUtil::UnmultiplyAlpha (&_image);
|
||||
return alloc_null ();
|
||||
|
||||
}
|
||||
|
||||
|
||||
value lime_jni_getenv () {
|
||||
|
||||
#ifdef ANDROID
|
||||
@@ -847,7 +868,9 @@ namespace lime {
|
||||
DEFINE_PRIM (lime_gamepad_event_manager_register, 2);
|
||||
DEFINE_PRIM (lime_gamepad_get_device_guid, 1);
|
||||
DEFINE_PRIM (lime_gamepad_get_device_name, 1);
|
||||
DEFINE_PRIM (lime_image_data_util_color_transform, 3);
|
||||
DEFINE_PRIM (lime_image_data_util_multiply_alpha, 1);
|
||||
DEFINE_PRIM (lime_image_data_util_unmultiply_alpha, 1);
|
||||
DEFINE_PRIM (lime_image_encode, 3);
|
||||
DEFINE_PRIM (lime_image_load, 1);
|
||||
DEFINE_PRIM (lime_jni_getenv, 0);
|
||||
|
||||
55
project/src/graphics/Image.cpp
Normal file
55
project/src/graphics/Image.cpp
Normal file
@@ -0,0 +1,55 @@
|
||||
#include <graphics/Image.h>
|
||||
|
||||
|
||||
namespace lime {
|
||||
|
||||
|
||||
static int id_buffer;
|
||||
static int id_height;
|
||||
static int id_offsetX;
|
||||
static int id_offsetY;
|
||||
static int id_width;
|
||||
static bool init = false;
|
||||
|
||||
|
||||
Image::Image () {
|
||||
|
||||
buffer = 0;
|
||||
height = 0;
|
||||
offsetX = 0;
|
||||
offsetY = 0;
|
||||
width = 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
Image::Image (value image) {
|
||||
|
||||
if (!init) {
|
||||
|
||||
id_buffer = val_id ("buffer");
|
||||
id_height = val_id ("height");
|
||||
id_offsetX = val_id ("offsetX");
|
||||
id_offsetY = val_id ("offsetY");
|
||||
id_width = val_id ("width");
|
||||
init = true;
|
||||
|
||||
}
|
||||
|
||||
width = val_int (val_field (image, id_width));
|
||||
height = val_int (val_field (image, id_height));
|
||||
buffer = new ImageBuffer (val_field (image, id_buffer));
|
||||
offsetX = val_int (val_field (image, id_offsetX));
|
||||
offsetY = val_int (val_field (image, id_offsetY));
|
||||
|
||||
}
|
||||
|
||||
|
||||
Image::~Image () {
|
||||
|
||||
delete buffer;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -5,13 +5,27 @@
|
||||
namespace lime {
|
||||
|
||||
|
||||
static long int __alpha16[256];
|
||||
static int __alpha16[0xFF];
|
||||
static int __clamp[0xFF + 0xFF + 1];
|
||||
|
||||
int initValues () {
|
||||
|
||||
for (int i = 0; i < 256; i++) {
|
||||
|
||||
__alpha16[i] = i * ((1 << 16) / 255);
|
||||
// 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;
|
||||
|
||||
}
|
||||
|
||||
@@ -22,18 +36,66 @@ namespace lime {
|
||||
static int initValues_ = initValues ();
|
||||
|
||||
|
||||
void ImageDataUtil::MultiplyAlpha (ByteArray* bytes) {
|
||||
void ImageDataUtil::ColorTransform (Image* image, Rectangle* rect, ColorMatrix* colorMatrix) {
|
||||
|
||||
int stride = image->buffer->width * 4;
|
||||
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);
|
||||
|
||||
uint8_t* data = (uint8_t*)image->buffer->data->Bytes ();
|
||||
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 ();
|
||||
|
||||
for (int row = rowStart; row < rowEnd; row++) {
|
||||
|
||||
for (int column = columnStart; column < columnEnd; column++) {
|
||||
|
||||
offset = (row * stride) + (column * 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;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void ImageDataUtil::MultiplyAlpha (Image* image) {
|
||||
|
||||
int a16 = 0;
|
||||
int length = bytes->Size () / 4;
|
||||
uint8_t* data = (uint8_t*)bytes->Bytes ();
|
||||
int length = image->buffer->data->Size () / 4;
|
||||
uint8_t* data = (uint8_t*)image->buffer->data->Bytes ();
|
||||
|
||||
for (int i = 0; i < length; i++) {
|
||||
|
||||
a16 = __alpha16[data[3]];
|
||||
data[0] = (data[0] * a16) >> 16;
|
||||
data[1] = (data[1] * a16) >> 16;
|
||||
data[2] = (data[2] * a16) >> 16;
|
||||
data[0] = (int (data[0]) * a16) >> 16;
|
||||
data[1] = (int (data[1]) * a16) >> 16;
|
||||
data[2] = (int (data[0]) * a16) >> 16;
|
||||
data += 4;
|
||||
|
||||
}
|
||||
@@ -41,8 +103,28 @@ namespace lime {
|
||||
}
|
||||
|
||||
|
||||
void ImageDataUtil::UnmultiplyAlpha (ByteArray* bytes) {
|
||||
void ImageDataUtil::UnmultiplyAlpha (Image* image) {
|
||||
|
||||
int length = image->buffer->data->Size () / 4;
|
||||
uint8_t* data = (uint8_t*)image->buffer->data->Bytes ();
|
||||
|
||||
int unmultiply;
|
||||
uint8_t a;
|
||||
|
||||
for (int i = 0; i < length; i++) {
|
||||
|
||||
a = data[3];
|
||||
|
||||
if (a != 0) {
|
||||
|
||||
unmultiply = 255.0 / a;
|
||||
data[0] = __clamp[data[0] * unmultiply];
|
||||
data[1] = __clamp[data[1] * unmultiply];
|
||||
data[2] = __clamp[data[2] * unmultiply];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
123
project/src/math/ColorMatrix.cpp
Normal file
123
project/src/math/ColorMatrix.cpp
Normal file
@@ -0,0 +1,123 @@
|
||||
#include <math/ColorMatrix.h>
|
||||
#include <utils/ByteArray.h>
|
||||
|
||||
|
||||
namespace lime {
|
||||
|
||||
|
||||
static int id_buffer;
|
||||
static bool init = false;
|
||||
|
||||
|
||||
ColorMatrix::ColorMatrix () {
|
||||
|
||||
for (int i = 0; i < 20; i++) {
|
||||
|
||||
if (i % 6 == 0) {
|
||||
|
||||
data[i] = 1;
|
||||
|
||||
} else {
|
||||
|
||||
data[i] = 0;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
ColorMatrix::ColorMatrix (value colorMatrix) {
|
||||
|
||||
if (!init) {
|
||||
|
||||
id_buffer = val_id ("buffer");
|
||||
init = true;
|
||||
|
||||
}
|
||||
|
||||
value buffer_value = val_field (colorMatrix, id_buffer);
|
||||
ByteArray bytes = ByteArray (buffer_value);
|
||||
float* src = (float*)bytes.Bytes ();
|
||||
|
||||
for (int i = 0; i < 20; i++) {
|
||||
|
||||
data[i] = src[i];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
ColorMatrix::~ColorMatrix () {
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
float ColorMatrix::GetAlphaMultiplier () {
|
||||
|
||||
return data[18];
|
||||
|
||||
}
|
||||
|
||||
|
||||
float ColorMatrix::GetAlphaOffset () {
|
||||
|
||||
return data[19] * 255;
|
||||
|
||||
}
|
||||
|
||||
|
||||
float ColorMatrix::GetBlueMultiplier () {
|
||||
|
||||
return data[12];
|
||||
|
||||
}
|
||||
|
||||
|
||||
float ColorMatrix::GetBlueOffset () {
|
||||
|
||||
return data[14] * 255;
|
||||
|
||||
}
|
||||
|
||||
|
||||
int ColorMatrix::GetColor () {
|
||||
|
||||
return ((int (GetRedOffset ()) << 16) | (int (GetGreenOffset ()) << 8) | int (GetBlueOffset ()));
|
||||
|
||||
}
|
||||
|
||||
|
||||
float ColorMatrix::GetGreenMultiplier () {
|
||||
|
||||
return data[6];
|
||||
|
||||
}
|
||||
|
||||
|
||||
float ColorMatrix::GetGreenOffset () {
|
||||
|
||||
return data[9] * 255;
|
||||
|
||||
}
|
||||
|
||||
|
||||
float ColorMatrix::GetRedMultiplier () {
|
||||
|
||||
return data[0];
|
||||
|
||||
}
|
||||
|
||||
|
||||
float ColorMatrix::GetRedOffset () {
|
||||
|
||||
return data[4] * 255;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
44
project/src/math/Rectangle.cpp
Normal file
44
project/src/math/Rectangle.cpp
Normal file
@@ -0,0 +1,44 @@
|
||||
#include <math/Rectangle.h>
|
||||
|
||||
|
||||
namespace lime {
|
||||
|
||||
|
||||
static int id_height;
|
||||
static int id_width;
|
||||
static int id_x;
|
||||
static int id_y;
|
||||
static bool init = false;
|
||||
|
||||
|
||||
Rectangle::Rectangle () {
|
||||
|
||||
height = 0;
|
||||
width = 0;
|
||||
x = 0;
|
||||
y = 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
Rectangle::Rectangle (value rect) {
|
||||
|
||||
if (!init) {
|
||||
|
||||
id_height = val_id ("height");
|
||||
id_width = val_id ("width");
|
||||
id_x = val_id ("x");
|
||||
id_y = val_id ("y");
|
||||
init = true;
|
||||
|
||||
}
|
||||
|
||||
width = val_number (val_field (rect, id_width));
|
||||
height = val_number (val_field (rect, id_height));
|
||||
x = val_number (val_field (rect, id_x));
|
||||
y = val_number (val_field (rect, id_y));
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user