Skip to content

Instantly share code, notes, and snippets.

@nanjizal
Created October 29, 2023 23:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nanjizal/e294685691ba380a78529d90b8d191aa to your computer and use it in GitHub Desktop.
Save nanjizal/e294685691ba380a78529d90b8d191aa to your computer and use it in GitHub Desktop.
StackImage
//https://try.haxe.org/#3C9bD72e
import haxe.ds.GenericStack; // assess to GenericCell
enum abstract ImageType(Int) {
var BYTES;
var ARRAY;
var UINT32ARRAY;
var VECTOR;
var GENERICSTACK;
}
class Test {
static function main() {
trace('ByteImage');
var byteImage = new ByteImage( 10, 10 );
for( i in 0...byteImage.length ){
byteImage[i] = Std.int(0xFF000000) + Std.random(0xFFFFFF);
}
trace( byteImage );
trace('ArrayImage');
var arrayImage = new ArrayImage( 10, 10 );
for( i in 0...arrayImage.length ){
arrayImage[i] = Std.int(0xFF000000) + Std.random(0xFFFFFF);
}
trace( arrayImage );
trace('UInt32ArrayImage');
var uint32ArrayImage = new UInt32ArrayImage( 10, 10 );
for( i in 0...uint32ArrayImage.length ){
uint32ArrayImage[i] = Std.int(0xFF000000) + Std.random(0xFFFFFF);
}
trace( uint32ArrayImage );
trace('VectorImage');
var vectorImage = new VectorImage( 10, 10 );
for( i in 0...vectorImage.length ){
vectorImage[i] = Std.int(0xFF000000) + Std.random(0xFFFFFF);
}
trace( vectorImage );
trace('StackImage');
var stackImage = new StackImage( 10, 10 );
for( i in 0...stackImage.length ){
stackImage[i] = Std.int(0xFF000000) + Std.random(0xFFFFFF);
}
trace( stackImage );
}
}
@:generic
@:structInit
class DataImage<T> {
public var width:Int;
public var height:Int;
var data:T;
public var imageType:ImageType;
public var count = 0;
public function new(width:Int, height:Int, data:T) {
this.width = width;
this.height = height;
this.data = data;
}
}
typedef TDataImage = {
public var width:Int;
public var height:Int;
public var count:Int;
public var imageType: ImageType;
public var length(get, never):Int;
public function get_length():Int;
@:arrayAccess public function set(index:Int, value:UInt):UInt;
@:arrayAccess public function get(index:Int):UInt;
public function zero():Void;
public function position(px:Int, py:Int):Int;
public function toString():String;
public function next():Int;
public function hasNext():Bool;
public function resetNext():Void;
}
interface IDataImage {
public var width:Int;
public var height:Int;
public var count:Int;
public var length(get, never):Int;
public function get_length():Int;
@:arrayAccess public function set(index:Int, value:UInt):UInt;
@:arrayAccess public function get(index:Int):UInt;
public function zero():Void;
public function position(px:Int, py:Int):Int;
public function toString():String;
public function next():Int;
public function hasNext():Bool;
public function resetNext():Void;
public var imageType:ImageType;
}
@:generic
@:structInit
abstract class ADataImage<T> extends DataImage<T> implements IDataImage {
public function new(width:Int, height:Int, data:T) {
super(width, height, data);
}
public var length(get, never):Int;
abstract public function get_length():Int;
@:arrayAccess
abstract public function set(index:Int, value:UInt):UInt;
@:arrayAccess
abstract public function get(index:Int):UInt;
abstract public function zero():Void;
abstract public function position(px:Int, py:Int):Int;
abstract public function toString():String;
public inline function resetNext() {
count = 0;
}
abstract public function hasNext():Bool;
abstract public function next():Int;
}
@:forward
@:transient
abstract ArrayImage(ADataImage<Array<Int>>) from ADataImage<Array<Int>> to ADataImage<Array<Int>> {
public inline function new(w:Int, h:Int) {
this = {width: w, height: h, data: new Array<Int>()};
this.imageType = ImageType.ARRAY;
zero();
}
@:access(ADataImage)
@:arrayAccess
public inline function set(index:Int, value:UInt):UInt {
this.data[index] = value;
return value;
}
@:access(ADataImage)
@:arrayAccess
public inline function get(index:Int):UInt
return this.data[index];
@:access(ADataImage)
public inline function zero() {
for (i in 0...length)
this.data[i] = 0;
}
public inline function position(px:Float, py:Float):Int {
// key
return Std.int(py * this.width + px);
}
public var length(get, never):Int;
public inline function get_length():Int {
return Std.int(this.width * this.height);
}
@:access(ADataImage)
public inline function toString() {
return this.data.toString();
}
}
@:forward
@:transient
abstract ByteImage(ADataImage<haxe.io.Bytes>) from ADataImage<haxe.io.Bytes> to ADataImage<haxe.io.Bytes> {
public inline function new(w:Int, h:Int) {
this = {width: w, height: h, data: haxe.io.Bytes.alloc(w * h * 4)};
this.imageType = ImageType.BYTES;
zero();
}
@:access(ADataImage)
public inline function zero() {
var w = 0;
for (y in 0...this.height) {
for (x in 0...this.width) {
this.data.set(w++, 0);
this.data.set(w++, 0);
this.data.set(w++, 0);
this.data.set(w++, 0);
}
}
}
public inline function position(px:Float, py:Float):Int {
// key
return Std.int(py * this.width + px);
}
@:access(ADataImage)
@:arrayAccess
public inline function get(key:Int):Int {
return (this.data.getInt32(Std.int(key * 4)));
}
@:access(ADataImage)
@:arrayAccess
public inline function set(key:Int, col:Int):Int {
this.data.setInt32(Std.int(key * 4), col);
return col;
}
public var length(get, never):Int;
inline function get_length():Int {
return Std.int(this.width * this.height);
}
public inline function toString() {
var str = '[';
for( i in 0...length ) str += Std.string( abstract[ i ] ) +',';
return str.substr( 0, str.length - 1 ) + ']';
}
public inline function hasNext():Bool {
return (this.count < abstract.length);
}
public inline function next() {
return get(this.count++);
}
}
@:forward
@:transient
abstract UInt32ArrayImage(ADataImage<haxe.io.UInt32Array>) from ADataImage<haxe.io.UInt32Array> to ADataImage<haxe.io.UInt32Array> {
public inline function new(w:Int, h:Int) {
this = {
width: w,
height: h,
data: new haxe.io.UInt32Array(Std.int(w * h))
};
this.imageType = ImageType.UINT32ARRAY;
zero();
}
@:access(ADataImage)
@:arrayAccess
public inline function set(index:Int, value:UInt):UInt {
this.data[index] = value;
return value;
}
@:access(ADataImage)
@:arrayAccess
public inline function get(index:Int):UInt {
return this.data[index];
}
@:access(ADataImage)
public inline function zero() {
for (i in 0...length)
this.data[i] = 0;
}
public inline function position(px:Float, py:Float):Int {
// key
return Std.int(py * this.width + px);
}
public var length(get, never):Int;
inline function get_length():Int {
return Std.int(this.width * this.height);
}
public inline function toString() {
var str = '[';
for( i in 0...length ) str += Std.string( abstract[ i ] ) +',';
return str.substr( 0, str.length - 1 ) + ']';
}
public inline function hasNext():Bool {
return (this.count < abstract.length);
}
public inline function next() {
return get(this.count++);
}
}
@:forward
@:transient
abstract VectorImage(ADataImage<haxe.ds.Vector<Int>>) from ADataImage<haxe.ds.Vector<Int>> to ADataImage<haxe.ds.Vector<Int>> {
public inline function new(w:Int, h:Int) {
this = {width: w, height: h, data: new haxe.ds.Vector<Int>(Std.int(w * h))};
this.imageType = ImageType.VECTOR;
zero();
}
@:access(ADataImage)
@:arrayAccess
public inline function set(index:Int, value:UInt):UInt {
this.data[index] = value;
return value;
}
@:access(ADataImage)
@:arrayAccess
public inline function get(index:Int):UInt
return this.data[index];
@:access(ADataImage)
public inline function zero()
for (i in 0...length)
this.data[i] = 0;
public var length(get, never):Int;
public inline function position(px:Float, py:Float):Int {
// key
return Std.int(py * this.width + px);
}
inline function get_length():Int {
return Std.int(this.width * this.height);
}
public inline function toString() {
var str = '[';
for( i in 0...length ) str += Std.string( abstract[ i ] ) +',';
return str.substr( 0, str.length - 1 ) + ']';
}
public inline function hasNext():Bool {
return (this.count < abstract.length);
}
public inline function next() {
return get(this.count++);
}
}
@:forward
@:transient
abstract StackImage(ADataImage<haxe.ds.GenericStack<Int>>) from ADataImage<haxe.ds.GenericStack<Int>> to ADataImage<haxe.ds.GenericStack<Int>> {
public inline function new(w:Int, h:Int) {
this = {width: w, height: h, data: new haxe.ds.GenericStack<Int>()};
this.imageType = ImageType.GENERICSTACK;
zero();
}
@:access(ADataImage)
@:arrayAccess
public inline function set( index: Int, value: UInt ):UInt {
var l = this.data.head;
var prev:GenericCell<Int> = null;
for( i in 0...index ) {
prev = l;
l = l.next;
}
if( prev == null ){
this.data.head = new GenericCell<Int>( value, l.next );
l = null;
} else {
prev.next = new GenericCell<Int>( value, l.next );
l = null;
}
return value;
}
@:access(ADataImage)
@:arrayAccess
public function get(index:Int):UInt {
var l = this.data.head;
var prev:GenericCell<Int> = l;
index += 1;
for( i in 0...index ) {
prev = l;
l = l.next;
}
return prev.elt;
}
@:access(ADataImage)
public inline function zero() {
var d = this.data;
if (d.isEmpty()) {
for (i in 0...length)
d.add( 0 );//length-i-1);
} else {
for (i in 0...length)
abstract[i] = 0;//i;
}
}
public var length(get, never):Int;
public inline function position(px:Float, py:Float):Int {
// key
return Std.int(py * this.width + px);
}
inline function get_length():Int {
return Std.int(this.width * this.height);
}
// TODO: consider substr to make same as others?
@:access(ADataImage)
public inline function toString() {
var str = '[';
for( i in 0...length ) str += Std.string( abstract[ i ] ) +',';
return str.substr( 0, str.length - 1 ) + ']';
}
public inline function hasNext():Bool {
return (this.count < abstract.length);
}
public inline function next() {
return get(this.count++);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment