| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314 |
- // Based on miniexr.cpp - public domain - 2013 Aras Pranckevicius / Unity Technologies
- // https://github.com/aras-p/miniexr
- // https://www.openexr.com/documentation/openexrfilelayout.pdf
- package arm.format;
- class ExrWriter {
- public function new(out: haxe.io.BytesOutput, width: Int, height: Int, src: haxe.io.Bytes, bits = 16, type = 1, off = 0) {
- out.writeByte(0x76); // magic
- out.writeByte(0x2f);
- out.writeByte(0x31);
- out.writeByte(0x01);
- out.writeByte(2); // version, scanline
- out.writeByte(0);
- out.writeByte(0);
- out.writeByte(0);
- out.writeString("channels");
- out.writeByte(0);
- out.writeString("chlist");
- out.writeByte(0);
- out.writeByte(55);
- out.writeByte(0);
- out.writeByte(0);
- out.writeByte(0);
- var attrib = bits == 16 ? 1 : 2; // half, float
- out.writeByte("B".code); // B
- out.writeByte(0);
- out.writeByte(attrib);
- out.writeByte(0);
- out.writeByte(0);
- out.writeByte(0);
- out.writeByte(0);
- out.writeByte(0);
- out.writeByte(0);
- out.writeByte(0);
- out.writeByte(1);
- out.writeByte(0);
- out.writeByte(0);
- out.writeByte(0);
- out.writeByte(1);
- out.writeByte(0);
- out.writeByte(0);
- out.writeByte(0);
- out.writeByte("G".code); // G
- out.writeByte(0);
- out.writeByte(attrib);
- out.writeByte(0);
- out.writeByte(0);
- out.writeByte(0);
- out.writeByte(0);
- out.writeByte(0);
- out.writeByte(0);
- out.writeByte(0);
- out.writeByte(1);
- out.writeByte(0);
- out.writeByte(0);
- out.writeByte(0);
- out.writeByte(1);
- out.writeByte(0);
- out.writeByte(0);
- out.writeByte(0);
- out.writeByte("R".code); // R
- out.writeByte(0);
- out.writeByte(attrib);
- out.writeByte(0);
- out.writeByte(0);
- out.writeByte(0);
- out.writeByte(0);
- out.writeByte(0);
- out.writeByte(0);
- out.writeByte(0);
- out.writeByte(1);
- out.writeByte(0);
- out.writeByte(0);
- out.writeByte(0);
- out.writeByte(1);
- out.writeByte(0);
- out.writeByte(0);
- out.writeByte(0);
- out.writeByte(0);
- out.writeString("compression");
- out.writeByte(0);
- out.writeString("compression");
- out.writeByte(0);
- out.writeByte(1);
- out.writeByte(0);
- out.writeByte(0);
- out.writeByte(0);
- out.writeByte(0); // no compression
- out.writeString("dataWindow");
- out.writeByte(0);
- out.writeString("box2i");
- out.writeByte(0);
- out.writeByte(16);
- out.writeByte(0);
- out.writeByte(0);
- out.writeByte(0);
- out.writeByte(0);
- out.writeByte(0);
- out.writeByte(0);
- out.writeByte(0);
- out.writeByte(0);
- out.writeByte(0);
- out.writeByte(0);
- out.writeByte(0);
- var ww = width - 1;
- var hh = height - 1;
- out.writeByte(ww & 0xff);
- out.writeByte((ww >> 8) & 0xff);
- out.writeByte((ww >> 16) & 0xff);
- out.writeByte((ww >> 24) & 0xff);
- out.writeByte(hh & 0xff);
- out.writeByte((hh >> 8) & 0xff);
- out.writeByte((hh >> 16) & 0xff);
- out.writeByte((hh >> 24) & 0xff);
- out.writeString("displayWindow");
- out.writeByte(0);
- out.writeString("box2i");
- out.writeByte(0);
- out.writeByte(16);
- out.writeByte(0);
- out.writeByte(0);
- out.writeByte(0);
- out.writeByte(0);
- out.writeByte(0);
- out.writeByte(0);
- out.writeByte(0);
- out.writeByte(0);
- out.writeByte(0);
- out.writeByte(0);
- out.writeByte(0);
- out.writeByte(ww & 0xff);
- out.writeByte((ww >> 8) & 0xff);
- out.writeByte((ww >> 16) & 0xff);
- out.writeByte((ww >> 24) & 0xff);
- out.writeByte(hh & 0xff);
- out.writeByte((hh >> 8) & 0xff);
- out.writeByte((hh >> 16) & 0xff);
- out.writeByte((hh >> 24) & 0xff);
- out.writeString("lineOrder");
- out.writeByte(0);
- out.writeString("lineOrder");
- out.writeByte(0);
- out.writeByte(1);
- out.writeByte(0);
- out.writeByte(0);
- out.writeByte(0);
- out.writeByte(0); // increasing Y
- out.writeString("pixelAspectRatio");
- out.writeByte(0);
- out.writeString("float");
- out.writeByte(0);
- out.writeByte(4);
- out.writeByte(0);
- out.writeByte(0);
- out.writeByte(0);
- out.writeByte(0); // 1.0f
- out.writeByte(0);
- out.writeByte(0x80);
- out.writeByte(0x3f);
- out.writeString("screenWindowCenter");
- out.writeByte(0);
- out.writeString("v2f");
- out.writeByte(0);
- out.writeByte(8);
- out.writeByte(0);
- out.writeByte(0);
- out.writeByte(0);
- out.writeByte(0);
- out.writeByte(0);
- out.writeByte(0);
- out.writeByte(0);
- out.writeByte(0);
- out.writeByte(0);
- out.writeByte(0);
- out.writeByte(0);
- out.writeString("screenWindowWidth");
- out.writeByte(0);
- out.writeString("float");
- out.writeByte(0);
- out.writeByte(4);
- out.writeByte(0);
- out.writeByte(0);
- out.writeByte(0);
- out.writeByte(0); // 1.0f
- out.writeByte(0);
- out.writeByte(0x80);
- out.writeByte(0x3f);
- out.writeByte(0); // end of header
- var channels = 4;
- var byteSize = bits == 16 ? 2 : 4;
- var kHeaderSize = out.length;
- var kScanlineTableSize = 8 * height;
- var pixelRowSize = width * 3 * byteSize;
- var fullRowSize = pixelRowSize + 8;
- // line offset table
- var ofs = kHeaderSize + kScanlineTableSize;
- for (y in 0...height) {
- out.writeByte(ofs & 0xff);
- out.writeByte((ofs >> 8) & 0xff);
- out.writeByte((ofs >> 16) & 0xff);
- out.writeByte((ofs >> 24) & 0xff);
- out.writeByte(0);
- out.writeByte(0);
- out.writeByte(0);
- out.writeByte(0);
- ofs += fullRowSize;
- }
- // scanline data
- var stride = channels * byteSize;
- var pos = 0;
- function writeLine16(bytePos: Int) {
- for (x in 0...width) {
- out.writeByte(src.get(bytePos ));
- out.writeByte(src.get(bytePos + 1));
- bytePos += stride;
- }
- }
- function writeLine32(bytePos: Int) {
- for (x in 0...width) {
- out.writeByte(src.get(bytePos ));
- out.writeByte(src.get(bytePos + 1));
- out.writeByte(src.get(bytePos + 2));
- out.writeByte(src.get(bytePos + 3));
- bytePos += stride;
- }
- }
- var writeLine = bits == 16 ? writeLine16 : writeLine32;
- function writeBGR(off: Int) {
- writeLine(pos + byteSize * 2);
- writeLine(pos + byteSize);
- writeLine(pos);
- }
- function writeSingle(off: Int) {
- writeLine(pos + off * byteSize);
- writeLine(pos + off * byteSize);
- writeLine(pos + off * byteSize);
- }
- var writeData = type == 1 ? writeBGR : writeSingle;
- for (y in 0...height) {
- // coordinate
- out.writeByte(y & 0xff);
- out.writeByte((y >> 8) & 0xff);
- out.writeByte((y >> 16) & 0xff);
- out.writeByte((y >> 24) & 0xff);
- // data size
- out.writeByte(pixelRowSize & 0xff);
- out.writeByte((pixelRowSize >> 8) & 0xff);
- out.writeByte((pixelRowSize >> 16) & 0xff);
- out.writeByte((pixelRowSize >> 24) & 0xff);
- // data
- writeData(off);
- pos += width * stride;
- }
- }
- }
|