1 /** 2 Copyright: Copyright (c) 2017-2018 Andrey Penechko. 3 License: $(WEB boost.org/LICENSE_1_0.txt, Boost License 1.0). 4 Authors: Andrey Penechko. 5 */ 6 7 module voxelman.graphics.bitmap; 8 9 import voxelman.algorithm.arraycopy2d; 10 import voxelman.math; 11 import voxelman.graphics.color; 12 import dlib.image.image : ImageRGBA8, SuperImage; 13 import dlib.image.color; 14 15 class Bitmap : ImageRGBA8 16 { 17 public: 18 19 this(uint w, uint h) 20 { 21 super(w, h); 22 } 23 24 this(SuperImage image) 25 { 26 super(0,0); 27 this._width = image.width; 28 this._height = image.height; 29 30 if (pixelFormat == image.pixelFormat) 31 { 32 this._bitDepth = image.bitDepth; 33 this._channels = image.channels; 34 this._pixelSize = image.pixelSize; 35 this._data = image.data; 36 } 37 else 38 { 39 allocateData(); 40 foreach(x; 0..image.width) 41 foreach(y; 0..image.height) 42 this[x, y] = Color4ub(image[x, y].convert(8)); 43 } 44 } 45 46 ivec2 size() 47 { 48 return ivec2(width, height); 49 } 50 51 override Color4f opIndexAssign(Color4f c, int x, int y) 52 { 53 return super.opIndexAssign(c, x, y); 54 } 55 56 void opIndexAssign(Color4ub color, int x, int y) 57 { 58 auto offset = (this._width * y + x) * 4; 59 _data[offset+0] = color.r; 60 _data[offset+1] = color.g; 61 _data[offset+2] = color.b; 62 _data[offset+3] = color.a; 63 } 64 65 void resize(ivec2 newSize) 66 { 67 if (newSize == size) return; 68 69 auto newData = new ubyte[newSize.x * newSize.y * _pixelSize]; 70 71 auto sourceSize = ivec2(_width * _pixelSize, _height); 72 auto sourceSubRect = irect(ivec2(0,0), sourceSize); 73 74 auto destSize = ivec2(newSize.x * _pixelSize, newSize.y); 75 auto destSubRectPos = ivec2(0,0); 76 77 setSubArray2d(_data, sourceSize, sourceSubRect, 78 newData, destSize, destSubRectPos); 79 80 _data = newData; 81 _width = newSize.x; 82 _height = newSize.y; 83 } 84 85 void fillSubRect(irect destRect, Color4ub color) 86 { 87 foreach(y; destRect.y..destRect.endY) 88 foreach(x; destRect.x..destRect.endX) 89 this[x, y] = color; 90 } 91 92 void putSubRect(in Bitmap source, irect sourceSubRect, ivec2 destPos) 93 { 94 auto sourceSize = ivec2(source._width * source._pixelSize, source._height); 95 auto destSize = ivec2(_width * _pixelSize, _height); 96 97 sourceSubRect.width *= source._pixelSize; 98 sourceSubRect.x *= source._pixelSize; 99 destPos.x *= _pixelSize; 100 101 setSubArray2d(source._data, sourceSize, sourceSubRect, 102 _data, destSize, destPos); 103 } 104 105 void putRect(in Bitmap source, ivec2 destPos) 106 { 107 auto sourceSize = ivec2(source._width * source._pixelSize, source._height); 108 auto sourceSubRect = irect(ivec2(0,0), sourceSize); 109 110 auto destSize = ivec2(_width * _pixelSize, _height); 111 112 setSubArray2d(source._data, sourceSize, sourceSubRect, 113 _data, destSize, destPos); 114 } 115 }