Some work on pixel formats
This commit is contained in:
@@ -58,6 +58,7 @@ class Image {
|
||||
public var buffer:ImageBuffer;
|
||||
public var data (get, set):UInt8Array;
|
||||
public var dirty:Bool;
|
||||
public var format (get, set):PixelFormat;
|
||||
public var height:Int;
|
||||
public var offsetX:Int;
|
||||
public var offsetY:Int;
|
||||
@@ -1172,6 +1173,34 @@ class Image {
|
||||
}
|
||||
|
||||
|
||||
private function get_format ():PixelFormat {
|
||||
|
||||
return buffer.format;
|
||||
|
||||
}
|
||||
|
||||
|
||||
private function set_format (value:PixelFormat):PixelFormat {
|
||||
|
||||
if (buffer.format != value) {
|
||||
|
||||
switch (type) {
|
||||
|
||||
case DATA:
|
||||
|
||||
ImageDataUtil.setFormat (this, value);
|
||||
|
||||
default:
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return buffer.format = value;
|
||||
|
||||
}
|
||||
|
||||
|
||||
private function get_powerOfTwo ():Bool {
|
||||
|
||||
return ((buffer.width != 0) && ((buffer.width & (~buffer.width + 1)) == buffer.width)) && ((buffer.height != 0) && ((buffer.height & (~buffer.height + 1)) == buffer.height));
|
||||
|
||||
@@ -2,6 +2,7 @@ package lime.graphics;
|
||||
|
||||
|
||||
import haxe.io.Bytes;
|
||||
import lime.graphics.cairo.CairoSurface;
|
||||
import lime.utils.ByteArray;
|
||||
import lime.utils.UInt8Array;
|
||||
|
||||
@@ -24,9 +25,11 @@ class ImageBuffer {
|
||||
|
||||
public var bitsPerPixel:Int;
|
||||
public var data:UInt8Array;
|
||||
public var format:PixelFormat;
|
||||
public var height:Int;
|
||||
public var premultiplied:Bool;
|
||||
public var src (get, set):Dynamic;
|
||||
public var stride (get, never):Int;
|
||||
public var transparent:Bool;
|
||||
public var width:Int;
|
||||
|
||||
@@ -38,12 +41,13 @@ class ImageBuffer {
|
||||
@:noCompletion private var __srcImageData:#if (js && html5) ImageData #else Dynamic #end;
|
||||
|
||||
|
||||
public function new (data:UInt8Array = null, width:Int = 0, height:Int = 0, bitsPerPixel:Int = 4) {
|
||||
public function new (data:UInt8Array = null, width:Int = 0, height:Int = 0, bitsPerPixel:Int = 4, format:PixelFormat = null) {
|
||||
|
||||
this.data = data;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.bitsPerPixel = bitsPerPixel;
|
||||
this.format = (format == null ? RGBA : format);
|
||||
transparent = true;
|
||||
|
||||
}
|
||||
@@ -169,4 +173,11 @@ class ImageBuffer {
|
||||
}
|
||||
|
||||
|
||||
private function get_stride ():Int {
|
||||
|
||||
return width * 4;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,9 +1,10 @@
|
||||
package lime.graphics;
|
||||
|
||||
|
||||
enum PixelFormat {
|
||||
@:enum abstract PixelFormat(Int) from Int to Int {
|
||||
|
||||
RGBA;
|
||||
ARGB;
|
||||
public var RGBA = 0;
|
||||
public var ARGB = 1;
|
||||
public var BGRA = 2;
|
||||
|
||||
}
|
||||
@@ -1,8 +1,11 @@
|
||||
package lime.graphics.cairo;
|
||||
|
||||
|
||||
import lime.graphics.Image;
|
||||
import lime.system.System;
|
||||
|
||||
@:access(haxe.io.Bytes)
|
||||
|
||||
|
||||
abstract CairoSurface(Dynamic) {
|
||||
|
||||
@@ -51,6 +54,17 @@ abstract CairoSurface(Dynamic) {
|
||||
}
|
||||
|
||||
|
||||
public static function fromImage (image:Image):CairoSurface {
|
||||
|
||||
#if lime_cairo
|
||||
return createForData (image.data.buffer.__getNativePointer (), CairoFormat.ARGB32, image.width, image.height, image.buffer.stride);
|
||||
#else
|
||||
return null;
|
||||
#end
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// Get & Set Methods
|
||||
|
||||
@@ -4,6 +4,7 @@ package lime.graphics.utils;
|
||||
import haxe.ds.Vector;
|
||||
import lime.graphics.Image;
|
||||
import lime.graphics.ImageBuffer;
|
||||
import lime.graphics.PixelFormat;
|
||||
import lime.math.ColorMatrix;
|
||||
import lime.math.Rectangle;
|
||||
import lime.math.Vector2;
|
||||
@@ -675,7 +676,7 @@ class ImageDataUtil {
|
||||
#end
|
||||
|
||||
#if ((cpp || neko) && !disable_cffi)
|
||||
if (!System.disableCFFI) byteArray = lime_image_data_util_get_pixels (image, rect, format == ARGB ? 1 : 0); else
|
||||
if (!System.disableCFFI) byteArray = lime_image_data_util_get_pixels (image, rect, format); else
|
||||
#end
|
||||
{
|
||||
|
||||
@@ -935,6 +936,95 @@ class ImageDataUtil {
|
||||
}
|
||||
|
||||
|
||||
public static function setFormat (image:Image, format:PixelFormat):Void {
|
||||
|
||||
var data = image.buffer.data;
|
||||
if (data == null) return;
|
||||
|
||||
#if ((cpp || neko) && !disable_cffi)
|
||||
if (!System.disableCFFI) lime_image_data_util_set_format (image, format); else
|
||||
#end
|
||||
{
|
||||
|
||||
var index, a16;
|
||||
var length = Std.int (data.length / 4);
|
||||
var r1, g1, b1, a1, r2, g2, b2, a2;
|
||||
var r, g, b, a;
|
||||
|
||||
switch (image.format) {
|
||||
|
||||
case RGBA:
|
||||
|
||||
r1 = 0;
|
||||
g1 = 1;
|
||||
b1 = 2;
|
||||
a1 = 3;
|
||||
|
||||
case ARGB:
|
||||
|
||||
r1 = 1;
|
||||
g1 = 2;
|
||||
b1 = 3;
|
||||
a1 = 0;
|
||||
|
||||
case BGRA:
|
||||
|
||||
r1 = 2;
|
||||
g1 = 1;
|
||||
b1 = 0;
|
||||
a1 = 3;
|
||||
|
||||
}
|
||||
|
||||
switch (format) {
|
||||
|
||||
case RGBA:
|
||||
|
||||
r2 = 0;
|
||||
g2 = 1;
|
||||
b2 = 2;
|
||||
a2 = 3;
|
||||
|
||||
case ARGB:
|
||||
|
||||
r2 = 1;
|
||||
g2 = 2;
|
||||
b2 = 3;
|
||||
a2 = 0;
|
||||
|
||||
case BGRA:
|
||||
|
||||
r2 = 2;
|
||||
g2 = 1;
|
||||
b2 = 0;
|
||||
a2 = 3;
|
||||
|
||||
}
|
||||
|
||||
for (i in 0...length) {
|
||||
|
||||
index = i * 4;
|
||||
|
||||
r = data[index + r1];
|
||||
g = data[index + g1];
|
||||
b = data[index + b1];
|
||||
a = data[index + a1];
|
||||
|
||||
data[index + r2] = r;
|
||||
data[index + g2] = g;
|
||||
data[index + b2] = b;
|
||||
data[index + a2] = a;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
image.buffer.format = format;
|
||||
image.dirty = true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static function setPixel (image:Image, x:Int, y:Int, color:Int, format:PixelFormat):Void {
|
||||
|
||||
var data = image.buffer.data;
|
||||
@@ -1000,7 +1090,7 @@ class ImageDataUtil {
|
||||
if (image.buffer.data == null) return;
|
||||
|
||||
#if ((cpp || neko) && !disable_cffi)
|
||||
if (!System.disableCFFI) lime_image_data_util_set_pixels (image, rect, byteArray, format == ARGB ? 1 : 0); else
|
||||
if (!System.disableCFFI) lime_image_data_util_set_pixels (image, rect, byteArray, format); else
|
||||
#end
|
||||
{
|
||||
|
||||
@@ -1127,6 +1217,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_format = System.load ("lime", "lime_image_data_util_set_format", 2);
|
||||
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
|
||||
|
||||
@@ -1002,6 +1002,15 @@ class ByteArray #if !js extends Bytes implements ArrayAccess<Int> implements IDa
|
||||
#end
|
||||
|
||||
|
||||
#if (cpp || neko || nodejs)
|
||||
public function __getNativePointer ():Dynamic {
|
||||
|
||||
return lime_byte_array_get_native_pointer (this);
|
||||
|
||||
}
|
||||
#end
|
||||
|
||||
|
||||
#if js
|
||||
private function __getUTFBytesCount (value:String):Int {
|
||||
|
||||
@@ -1154,6 +1163,7 @@ class ByteArray #if !js extends Bytes implements ArrayAccess<Int> implements IDa
|
||||
|
||||
|
||||
|
||||
private static var lime_byte_array_get_native_pointer = System.load ("lime", "lime_byte_array_get_native_pointer", 1);
|
||||
private static var lime_byte_array_overwrite_file = System.load ("lime", "lime_byte_array_overwrite_file", 2);
|
||||
private static var lime_byte_array_read_file = System.load ("lime", "lime_byte_array_read_file", 1);
|
||||
private static var lime_lzma_decode = System.load ("lime", "lime_lzma_decode", 1);
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
|
||||
#include <hx/CFFI.h>
|
||||
#include <graphics/PixelFormat.h>
|
||||
#include <utils/ByteArray.h>
|
||||
|
||||
|
||||
@@ -24,6 +25,7 @@ namespace lime {
|
||||
|
||||
int bpp;
|
||||
ByteArray *data;
|
||||
PixelFormat format;
|
||||
int height;
|
||||
int width;
|
||||
bool transparent;
|
||||
|
||||
@@ -8,7 +8,8 @@ namespace lime {
|
||||
enum PixelFormat {
|
||||
|
||||
RGBA,
|
||||
ARGB
|
||||
ARGB,
|
||||
BGRA
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -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 SetFormat (Image* image, PixelFormat format);
|
||||
static void SetPixels (Image* image, Rectangle* rect, ByteArray* bytes, PixelFormat format);
|
||||
static void UnmultiplyAlpha (Image* image);
|
||||
|
||||
|
||||
@@ -549,6 +549,16 @@ namespace lime {
|
||||
}
|
||||
|
||||
|
||||
value lime_image_data_util_set_format (value image, value format) {
|
||||
|
||||
Image _image = Image (image);
|
||||
PixelFormat _format = (PixelFormat)val_int (format);
|
||||
ImageDataUtil::SetFormat (&_image, _format);
|
||||
return alloc_null ();
|
||||
|
||||
}
|
||||
|
||||
|
||||
value lime_image_data_util_set_pixels (value image, value rect, value bytes, value format) {
|
||||
|
||||
Image _image = Image (image);
|
||||
@@ -985,6 +995,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_format, 2);
|
||||
DEFINE_PRIM (lime_image_data_util_set_pixels, 4);
|
||||
DEFINE_PRIM (lime_image_data_util_unmultiply_alpha, 1);
|
||||
DEFINE_PRIM (lime_image_encode, 3);
|
||||
|
||||
@@ -8,6 +8,7 @@ namespace lime {
|
||||
static int id_bpp;
|
||||
static int id_buffer;
|
||||
static int id_data;
|
||||
static int id_format;
|
||||
static int id_height;
|
||||
static int id_width;
|
||||
static int id_transparent;
|
||||
@@ -19,6 +20,7 @@ namespace lime {
|
||||
width = 0;
|
||||
height = 0;
|
||||
bpp = 4;
|
||||
format = RGBA;
|
||||
data = 0;
|
||||
transparent = false;
|
||||
|
||||
@@ -36,6 +38,7 @@ namespace lime {
|
||||
id_width = val_id ("width");
|
||||
id_height = val_id ("height");
|
||||
id_data = val_id ("data");
|
||||
id_format = val_id ("format");
|
||||
init = true;
|
||||
|
||||
}
|
||||
@@ -43,6 +46,7 @@ namespace lime {
|
||||
width = val_int (val_field (imageBuffer, id_width));
|
||||
height = val_int (val_field (imageBuffer, id_height));
|
||||
bpp = val_int (val_field (imageBuffer, id_bitsPerPixel));
|
||||
format = (PixelFormat)val_int (val_field (imageBuffer, id_format));
|
||||
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);
|
||||
@@ -103,6 +107,7 @@ namespace lime {
|
||||
id_width = val_id ("width");
|
||||
id_height = val_id ("height");
|
||||
id_data = val_id ("data");
|
||||
id_format = val_id ("format");
|
||||
init = true;
|
||||
|
||||
}
|
||||
@@ -113,6 +118,7 @@ namespace lime {
|
||||
alloc_field (mValue, id_bpp, alloc_int (bpp));
|
||||
alloc_field (mValue, id_transparent, alloc_bool (transparent));
|
||||
alloc_field (mValue, id_data, data->mValue);
|
||||
alloc_field (mValue, id_format, alloc_int (format));
|
||||
return mValue;
|
||||
|
||||
}
|
||||
|
||||
@@ -478,6 +478,90 @@ namespace lime {
|
||||
}
|
||||
|
||||
|
||||
void ImageDataUtil::SetFormat (Image* image, PixelFormat format) {
|
||||
|
||||
int index, a16;
|
||||
int length = image->buffer->data->Size () / 4;
|
||||
int r1, g1, b1, a1, r2, g2, b2, a2;
|
||||
int r, g, b, a;
|
||||
|
||||
switch (image->buffer->format) {
|
||||
|
||||
case RGBA:
|
||||
|
||||
r1 = 0;
|
||||
g1 = 1;
|
||||
b1 = 2;
|
||||
a1 = 3;
|
||||
break;
|
||||
|
||||
case ARGB:
|
||||
|
||||
r1 = 1;
|
||||
g1 = 2;
|
||||
b1 = 3;
|
||||
a1 = 0;
|
||||
break;
|
||||
|
||||
case BGRA:
|
||||
|
||||
r1 = 2;
|
||||
g1 = 1;
|
||||
b1 = 0;
|
||||
a1 = 3;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
switch (format) {
|
||||
|
||||
case RGBA:
|
||||
|
||||
r2 = 0;
|
||||
g2 = 1;
|
||||
b2 = 2;
|
||||
a2 = 3;
|
||||
break;
|
||||
|
||||
case ARGB:
|
||||
|
||||
r2 = 1;
|
||||
g2 = 2;
|
||||
b2 = 3;
|
||||
a2 = 0;
|
||||
break;
|
||||
|
||||
case BGRA:
|
||||
|
||||
r2 = 2;
|
||||
g2 = 1;
|
||||
b2 = 0;
|
||||
a2 = 3;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
unsigned char* data = image->buffer->data->Bytes ();
|
||||
|
||||
for (int i = 0; i < length; i++) {
|
||||
|
||||
index = i * 4;
|
||||
|
||||
r = data[index + r1];
|
||||
g = data[index + g1];
|
||||
b = data[index + b1];
|
||||
a = data[index + a1];
|
||||
|
||||
data[index + r2] = r;
|
||||
data[index + g2] = g;
|
||||
data[index + b2] = b;
|
||||
data[index + a2] = a;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void ImageDataUtil::SetPixels (Image* image, Rectangle* rect, ByteArray* bytes, PixelFormat format) {
|
||||
|
||||
if (format == RGBA && rect->width == image->buffer->width && rect->height == image->buffer->height && rect->x == 0 && rect->y == 0) {
|
||||
|
||||
@@ -138,7 +138,7 @@ namespace lime {
|
||||
|
||||
if (!val_is_null (bytes.mValue)) {
|
||||
|
||||
return alloc_int ((intptr_t)bytes.Bytes ());
|
||||
return alloc_float ((intptr_t)bytes.Bytes ());
|
||||
|
||||
}
|
||||
|
||||
@@ -146,6 +146,7 @@ namespace lime {
|
||||
|
||||
}
|
||||
|
||||
|
||||
value lime_byte_array_init (value inFactory, value inLen, value inResize, value inBytes) {
|
||||
|
||||
gByteArrayCreate = new AutoGCRoot (inFactory);
|
||||
|
||||
Reference in New Issue
Block a user