1 module lib; 2 3 version(lib){ 4 import utils.misc; 5 import pngtext; 6 import std..string; 7 import core.runtime; 8 import core.memory; 9 10 /// to init the runtime, idk why `shared static this` won't work 11 extern (C) void init(){ 12 rt_init(); 13 } 14 15 /// to terminate the runtime, idk why `shared static ~this` won't work 16 extern (C) void term(){ 17 if (dataRead.ptr !is null){ 18 .destroy (dataRead); 19 } 20 GC.collect(); 21 rt_term; 22 } 23 24 /// stores the return from readFromPng so the GC doesn't free that memory 25 private ubyte[] dataRead; 26 27 /// reads data from png image 28 extern (C) ubyte* readFromPng(char* fn, uint* length){ 29 string filename = fromStringz(fn).idup; 30 if (dataRead.ptr !is null){ 31 .destroy (dataRead); 32 } 33 try{ 34 dataRead = readDataFromPng(filename); 35 }catch (Exception e){ 36 *length = 0; 37 return null; 38 } 39 *length = cast(uint)dataRead.length; 40 return dataRead.ptr; 41 } 42 43 /// writes data to png image 44 /// 45 /// Returns: true if successful 46 extern (C) bool writeToPng(char* fn, char* oFn, ubyte* dataPtr, uint dataLength){ 47 string filename = fromStringz(fn).idup; 48 string outputFilename = fromStringz(oFn).idup; 49 ubyte[] data; 50 data.length = dataLength; 51 ubyte* ptr = dataPtr; 52 foreach (i; 0 .. dataLength){ 53 data[i] = *dataPtr; 54 dataPtr++; 55 } 56 try{ 57 return writeDataToPng(filename, outputFilename, data).length == 0? true : false; 58 }catch (Exception e){ 59 return false; 60 } 61 } 62 63 /// returns the number of bytes that can be stored 64 extern (C) uint pngCapacity(char* fn, ubyte density){ 65 string filename = fromStringz(fn).idup; 66 return cast(uint)calculatePngCapacity (filename, density); 67 } 68 69 /// returns a float number, which tells the quality of the output image 70 /// 71 /// the number is the average number of bits used per one byte (each pixel = 4 bytes). Only bytes from pixels which are used to hold 72 /// data are considered in the calcualtion, untouched pixels are not counted as they remain as-they-were; 73 /// the number can be at max 8 (saturated image), lowest 0 (no data & highest quality). Lower means higher quality. 74 extern (C) float getQuality(char* fn, uint dataLength){ 75 string filename = fromStringz(fn).idup; 76 // get the optimum quality assoc_array 77 uinteger[ubyte] optimumQ = calculateOptimumDensity(filename , dataLength); 78 // The formula is (index * value at index, for each index) / (total used bytes, = sum of values at all indexes) 79 uinteger numerator = 0, denominator = 0; 80 foreach (index, value; optimumQ){ 81 numerator += index * value; 82 denominator += value; 83 } 84 return (cast(float)numerator*8) / (cast(float)denominator*8); 85 86 } 87 }