1 module magicalrainbows.raw; 2 3 import std.conv; 4 5 import magicalrainbows.formats; 6 import magicalrainbows.utils; 7 8 enum SupportedFormat { bgr555, bgr565, rgb888, rgba8888, bgr222, bgr333md } 9 10 /++ 11 + Reads and converts a colour from a raw byte array to a specified colour format. 12 + 13 + Params: format = data format to read 14 + data = raw data to read from 15 + ColourFormat = colour format to convert to 16 + Returns: a colour in the specified format 17 +/ 18 auto bytesToColor(ColourFormat = RGB888)(const ubyte[] data, SupportedFormat format) if (isColourFormat!ColourFormat) { 19 static ColourFormat getColour(T)(const ubyte[] data) { 20 assert(data.length == T.sizeof, "Data length does not match colour size"); 21 return data.to!(ubyte[T.sizeof]).read!T().convert!ColourFormat(); 22 } 23 final switch (format) { 24 case SupportedFormat.bgr222: 25 return getColour!BGR222(data); 26 case SupportedFormat.bgr333md: 27 return getColour!BGR333MD(data); 28 case SupportedFormat.bgr555: 29 return getColour!BGR555(data); 30 case SupportedFormat.bgr565: 31 return getColour!BGR565(data); 32 case SupportedFormat.rgb888: 33 return getColour!RGB888(data); 34 case SupportedFormat.rgba8888: 35 return getColour!RGBA8888(data); 36 } 37 } 38 /// 39 @safe pure unittest { 40 assert(bytesToColor([0xA9, 0xFF], SupportedFormat.bgr555) == RGB888(72, 232, 248)); 41 assert(bytesToColor([0xA9, 0xFF], SupportedFormat.bgr565) == RGB888(72, 244, 248)); 42 assert(bytesToColor([72, 244, 248], SupportedFormat.rgb888) == RGB888(72, 244, 248)); 43 } 44 auto bytesToColors(ColourFormat = RGB888)(const ubyte[] data, SupportedFormat format) if (isColourFormat!ColourFormat) { 45 import std.algorithm.iteration : map; 46 import std.array: array; 47 import std.range : chunks; 48 static ColourFormat[] getPalette(T)(const ubyte[] data) { 49 return data.chunks(T.sizeof).map!(x => x.read!T.convert!ColourFormat).array; 50 51 } 52 final switch (format) { 53 case SupportedFormat.bgr222: 54 return getPalette!BGR222(data); 55 case SupportedFormat.bgr333md: 56 return getPalette!BGR333MD(data); 57 case SupportedFormat.bgr555: 58 return getPalette!BGR555(data); 59 case SupportedFormat.bgr565: 60 return getPalette!BGR565(data); 61 case SupportedFormat.rgb888: 62 return getPalette!RGB888(data); 63 case SupportedFormat.rgba8888: 64 return getPalette!RGBA8888(data); 65 } 66 } 67 /// 68 @safe pure unittest { 69 assert(bytesToColors([0xA9, 0xFF], SupportedFormat.bgr555) == [RGB888(72, 232, 248)]); 70 assert(bytesToColors([0xA9, 0xFF, 0x0, 0x0], SupportedFormat.bgr555) == [RGB888(72, 232, 248), RGB888(0, 0, 0)]); 71 assert(bytesToColors([0xA9, 0xFF], SupportedFormat.bgr565) == [RGB888(72, 244, 248)]); 72 assert(bytesToColors([72, 244, 248], SupportedFormat.rgb888) == [RGB888(72, 244, 248)]); 73 } 74 75 ubyte[Format.sizeof] colourToBytes(Format)(Format data) if (isColourFormat!Format) { 76 return data.asBytes(); 77 } 78 /// 79 @safe pure unittest { 80 assert(colourToBytes(BGR555(9, 29, 31)) == [0xA9, 0x7F]); 81 assert(colourToBytes(BGR565(9, 58, 31)) == [0x49, 0xFF]); 82 assert(colourToBytes(RGB888(72, 232, 248)) == [72, 232, 248]); 83 } 84 85 ubyte[] colourToBytes(T)(T data, SupportedFormat format) if (isColourFormat!T) { 86 ubyte[] output; 87 final switch (format) { 88 case SupportedFormat.bgr222: 89 output = colourToBytes(data.convert!BGR222)[].dup; 90 break; 91 case SupportedFormat.bgr333md: 92 output = colourToBytes(data.convert!BGR333MD)[].dup; 93 break; 94 case SupportedFormat.bgr555: 95 output = colourToBytes(data.convert!BGR555)[].dup; 96 break; 97 case SupportedFormat.bgr565: 98 output = colourToBytes(data.convert!BGR565)[].dup; 99 break; 100 case SupportedFormat.rgb888: 101 output = colourToBytes(data.convert!RGB888)[].dup; 102 break; 103 case SupportedFormat.rgba8888: 104 output = colourToBytes(data.convert!RGBA8888)[].dup; 105 break; 106 } 107 return output; 108 } 109 /// 110 @safe pure unittest { 111 assert(colourToBytes(RGB888(72, 232, 248), SupportedFormat.bgr555) == [0xA9, 0x7F]); 112 assert(colourToBytes(RGB888(72, 232, 248), SupportedFormat.bgr565) == [0x49, 0xFF]); 113 assert(colourToBytes(RGB888(72, 232, 248), SupportedFormat.rgb888) == [72, 232, 248]); 114 } 115