Created
October 29, 2023 23:10
-
-
Save nanjizal/e294685691ba380a78529d90b8d191aa to your computer and use it in GitHub Desktop.
StackImage
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//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