1 module rip.processing.bitPlane; 2 3 private { 4 import std.algorithm; 5 import std.stdio; 6 7 import rip.concepts; 8 import rip.concepts.channel; 9 } 10 11 pure T getBitMask(T)(ubyte bitIndex) { 12 //Берём еденицу и сдвигаем её на bitIndex бит влево 13 //получаем 2 в степени bitIndex 14 return cast(T) (1 << bitIndex); 15 } 16 17 pure T getInvertBitMask(T) (ubyte bitIndex) { 18 return ~getBitMask!(T) (bitIndex); 19 } 20 21 bool getBit(T) (T value, ubyte index) { 22 return cast(bool)(value & getBitMask!T(index)); 23 } 24 25 auto generateBitRange(Range) (Range pixels, Channel channel, ubyte bitIndex) 26 if(isPixelRange!Range) 27 { 28 auto range = pixels 29 .map!((a) => channel.getValue(a).getBit(bitIndex)); 30 31 return range; 32 } 33 34 auto generateBitRange(Surface surface, Channel channel, ubyte index) { 35 return surface 36 //FIXME: Не работает через createFences 37 .getPixelsRange 38 .generateBitRange(channel, index); 39 } 40 41 auto drawBitRange(BitRange)(BitRange range) { 42 return range 43 .map!(a => a ? new RGBColor(255, 255, 255) : new RGBColor(0, 0, 0)); 44 } 45 46 enum BitOperation { 47 AND = "&", 48 OR = "|", 49 NOT = "~", 50 XOR = "^" 51 } 52 53 auto cutBitPlane(Range) (Range range, Channel channel, ubyte bitIndex) 54 if(isPixelRange!Range) 55 { 56 ubyte mask = getInvertBitMask!ubyte(bitIndex); 57 58 auto appMask(in RGBColor color) { 59 ubyte value = cast(ubyte)channel.getValue(color); 60 ubyte newValue = value & mask; 61 62 return channel.injectValue(color, newValue); 63 } 64 65 auto newRange = range 66 .map!appMask; 67 68 return newRange; 69 } 70 71 auto injectBitPlane(BitRange, PixelRange) (PixelRange pixels, BitRange bits, 72 Channel channel, ubyte bitIndex) 73 if(isPixelRange!PixelRange) 74 { 75 76 auto appMask(T)(T pair) { 77 78 auto color = pair[1]; 79 ubyte channelValue = cast(ubyte)channel.getValue(color); 80 81 ubyte mask; 82 ubyte newValue; 83 bool _bit = pair[0]; 84 85 if(_bit == true) { 86 mask = getBitMask!ubyte(bitIndex); 87 newValue = channelValue | mask; 88 } 89 else { 90 mask = getInvertBitMask!ubyte(bitIndex); 91 newValue = channelValue & mask; 92 } 93 94 return channel.injectValue(color, newValue); 95 } 96 97 return zip(bits, pixels).map!appMask; 98 } 99 100 auto processBitPlane(BitOperation op, Range1, Range2) 101 (Range1 range1, Range2 range2) { 102 103 mixin( 104 "return zip(range1, range2) 105 .map!((pair) => pair[0] " ~ op ~" pair[1]);" 106 ); 107 }