1 module converter; 2 3 //import imageformats; 4 5 import PixelPerfectEngine.graphics.bitmap; 6 import PixelPerfectEngine.extbmp.extbmp; 7 import PixelPerfectEngine.system.exc; 8 import PixelPerfectEngine.system.etc; 9 10 import derelict.freeimage.freeimage; 11 //import derelict.freeimage.functions; 12 import derelict.freeimage.types; 13 14 import std.stdio; 15 import std.path; 16 import std.bitmanip; 17 import std.conv; 18 19 /*Bitmap32Bit import32BitBitmapFromFile(string filename){ 20 21 FREE_IMAGE_FORMAT format; 22 switch(filename[filename.length-3..filename.length]){ 23 case "png": format = FIF_PNG; break; 24 case "tga": format = FIF_TARGA; break; 25 case "bmp": format = FIF_BMP; break; 26 default: break; 27 } 28 29 const char* fn = std.string.toStringz(filename); 30 FIBITMAP* source = FreeImage_Load(format, fn); 31 int iX = FreeImage_GetWidth(source), iY = FreeImage_GetHeight(source); 32 Bitmap32Bit result = new Bitmap32Bit(iX,iY); 33 switch(FreeImage_GetBPP(source)){ 34 case 32: 35 for(int y; y < iY; y++){ 36 for(int x; x < iX; x++){ 37 RGBQUAD c; FreeImage_GetPixelColor(source, x, iY - 1 - y, &c); 38 result.writePixel(x,y,c.rgbRed,c.rgbGreen,c.rgbBlue,c.rgbReserved); 39 //writeln(c.rgbRed,',',c.rgbGreen,',',c.rgbBlue,',',c.rgbReserved,','); 40 } 41 } 42 break; 43 default: 44 for(int y; y < iY; y++){ 45 for(int x; x < iX; x++){ 46 RGBQUAD c; FreeImage_GetPixelColor(source, x, iY - 1 - y, &c); 47 result.writePixel(x,y,c.rgbRed,c.rgbGreen,c.rgbBlue,255); 48 //writeln(c.rgbRed,',',c.rgbGreen,',',c.rgbBlue,',',c.rgbReserved,','); 49 } 50 } 51 break; 52 } 53 54 return result; 55 }*/ 56 57 enum NumberingStyle{ 58 DECIMAL = 0, 59 OCTAL = 1, 60 HEXADECIMAL = 2, 61 CHAR = 3, 62 WCHAR = 4 63 } 64 65 class ImportData{ 66 string[] ID; 67 string bitdepth, format; 68 int x, y, IDpos; 69 ushort paletteOffset; 70 NamingConvention nc; 71 this(string[] ID, string bitdepth, int x, int y, ushort paletteOffset){ 72 this.ID = ID; 73 this.bitdepth = bitdepth; 74 this.x = x; 75 this.y = y; 76 this.paletteOffset = paletteOffset; 77 //this.numOfDigits = numOfDigits; 78 } 79 this(NamingConvention nc, string bitdepth, int x, int y, ushort paletteOffset){ 80 this.nc = nc; 81 this.bitdepth = bitdepth; 82 this.x = x; 83 this.y = y; 84 this.paletteOffset = paletteOffset; 85 //this.numOfDigits = numOfDigits; 86 } 87 string getNextID(){ 88 if(nc is null){ 89 string result = ID[IDpos]; 90 IDpos++; 91 return result; 92 }else{ 93 string result = nc.wordA; 94 switch(nc.incrStyle){ 95 case NumberingStyle.OCTAL: result ~= intToOct(IDpos+nc.startingPoint,nc.format); break; 96 case NumberingStyle.HEXADECIMAL: result ~= intToHex(IDpos+nc.startingPoint,nc.format); break; 97 default: result ~= to!string(IDpos+nc.startingPoint); break; 98 } 99 IDpos++; 100 result ~= nc.wordB; 101 return result; 102 } 103 } 104 bool isMulti(){ 105 if(x > 0 && y > 0) return true; 106 return false; 107 } 108 109 } 110 111 class NamingConvention{ 112 string wordA, wordB; 113 NumberingStyle incrStyle; 114 int startingPoint, format; 115 this(string wordA, string wordB, NumberingStyle incrStyle, int startingPoint, int format){ 116 this.wordA = wordA; 117 this.wordB = wordB; 118 this.incrStyle = incrStyle; 119 this.startingPoint = startingPoint; 120 this.format = format; 121 } 122 } 123 124 public void importDirectlyToXMP(string path, ExtendibleBitmap target, ImportData id){ 125 FREE_IMAGE_FORMAT format; 126 switch(extension(path)){ 127 case ".png": format = FIF_PNG; break; 128 case ".tga": format = FIF_TARGA; break; 129 case ".bmp": format = FIF_BMP; break; 130 default: break; 131 } 132 const char* fn = std..string.toStringz(path); 133 FIBITMAP* source = FreeImage_Load(format, fn); 134 int iX = FreeImage_GetWidth(source), iY = FreeImage_GetHeight(source); 135 ubyte[] raw; ushort[] raw16; 136 switch(id.bitdepth){ 137 case "1bit": 138 BitArray ba = BitArray(cast(void[])raw, 0); 139 ba.length(iX * iY); 140 for(int y; y < iY; y++){ 141 for(int x; x < iX; x++){ 142 ubyte c; FreeImage_GetPixelIndex(source, x, iY - 1 - y, &c); 143 if(c != 0){ 144 ba[x + (iX * y)] = true; 145 } 146 } 147 } 148 break; 149 case "16bit": 150 for(int y; y < iY; y++){ 151 for(int x; x < iX; x++){ 152 ubyte c; FreeImage_GetPixelIndex(source, x, iY - 1 - y, &c); 153 raw16 ~= to!ushort(id.paletteOffset + c); 154 } 155 } 156 break; 157 default: 158 switch(FreeImage_GetBPP(source)){ 159 case 1,2,4,8: 160 for(int y; y < iY; y++){ 161 for(int x; x < iX; x++){ 162 ubyte c; FreeImage_GetPixelIndex(source, x, iY - 1 - y, &c); 163 raw ~= c; 164 } 165 } 166 break; 167 case 32: 168 for(int y; y < iY; y++){ 169 for(int x; x < iX; x++){ 170 RGBQUAD c; FreeImage_GetPixelColor(source, x, iY - 1 - y, &c); 171 //result.writePixel(x,y,c.rgbRed,c.rgbGreen,c.rgbBlue,c.rgbReserved); 172 //writeln(c.rgbRed,',',c.rgbGreen,',',c.rgbBlue,',',c.rgbReserved,','); 173 raw ~= [c.rgbRed,c.rgbGreen,c.rgbBlue,c.rgbReserved]; 174 } 175 } 176 break; 177 default: 178 for(int y; y < iY; y++){ 179 for(int x; x < iX; x++){ 180 RGBQUAD c; FreeImage_GetPixelColor(source, x, iY - 1 - y, &c); 181 //result.writePixel(x,y,c.rgbRed,c.rgbGreen,c.rgbBlue,255); 182 //writeln(c.rgbRed,',',c.rgbGreen,',',c.rgbBlue,',',c.rgbReserved,','); 183 raw ~= [c.rgbRed,c.rgbGreen,c.rgbBlue,255]; 184 } 185 } 186 break; 187 } 188 break; 189 } 190 if(id.isMulti){ 191 if(iX%id.x > 0 || iY%id.y > 0){ 192 throw new BitmapFormatException("Incorrect sizes for slicing!"); 193 } 194 if(id.bitdepth == "16bit"){ 195 //target.addBitmap(raw16,id.x,id.y,id.bitdepth,id.ID[0]); 196 for(int jY; jY < iY / id.y; jY++){ 197 for(int jX; jX < iX / id.x; jX++){ 198 ushort[] raw2; 199 for(int y; y < id.y; y++){ 200 int from = ((jY * id.y * iX) + (y * iX) + (jX * id.x)), t = from + id.x; 201 raw2 ~= raw16[from..t]; 202 } 203 target.addBitmap(raw2,id.x,id.y,id.bitdepth,id.getNextID(),id.format); 204 //si++; 205 } 206 } 207 }else{ 208 int pitch = 1; 209 if(id.bitdepth == "32bit")pitch = 4; 210 for(int jY; jY < iY / id.y; jY++){ 211 for(int jX; jX < iX / id.x; jX++){ 212 ubyte[] raw2; 213 for(int y; y < id.y; y++){ 214 int from = pitch * ((jY * id.y * iX) + (y * iX) + (jX * id.x)), t = from + (id.x * pitch); 215 raw2~= raw[from..t]; 216 } 217 target.addBitmap(raw2,id.x,id.y,id.bitdepth,id.getNextID(),id.format); 218 //si++; 219 } 220 } 221 222 } 223 }else{ 224 if(id.bitdepth == "16bit"){ 225 target.addBitmap(raw16,iX,iY,id.bitdepth,id.ID[0]); 226 }else{ 227 target.addBitmap(raw,iX,iY,id.bitdepth,id.ID[0],id.format); 228 } 229 } 230 } 231 232 public void importPaletteDirectlyToXMP(string path, ExtendibleBitmap target, string paletteID, ushort offset = 0){ 233 FREE_IMAGE_FORMAT format; 234 switch(extension(path)){ 235 case ".png": format = FIF_PNG; break; 236 case ".tga": format = FIF_TARGA; break; 237 case ".bmp": format = FIF_BMP; break; 238 default: break; 239 } 240 const char* fn = std..string.toStringz(path); 241 FIBITMAP* source = FreeImage_Load(format, fn); 242 uint bitdepth = FreeImage_GetBPP(source); 243 244 ubyte[] palette; 245 switch(bitdepth){ 246 case 4: palette.length = 64; break; 247 case 8: palette.length = 1024; break; 248 default: break; 249 } 250 RGBQUAD* colors = FreeImage_GetPalette(source); 251 //RGBQUAD.sizeof; 252 palette[0] = 0; 253 palette[1] = colors.rgbRed; 254 palette[2] = colors.rgbGreen; 255 palette[3] = colors.rgbBlue; 256 for(int i = 4; i < palette.length; i+=4){ 257 colors++; 258 palette[i] = 255; 259 palette[i + 1] = colors.rgbRed; 260 palette[i + 2] = colors.rgbGreen; 261 palette[i + 3] = colors.rgbBlue; 262 263 } 264 target.addPalette(cast(void[])palette, paletteID); 265 } 266 267 public Bitmap32Bit getBitmapPreview(ExtendibleBitmap xmp, string ID){ 268 Bitmap32Bit result; 269 switch(xmp.getBitDepth(ID)){ 270 case "32bit": 271 result = new Bitmap32Bit(cast(ubyte[])xmp.getBitmap(ID),xmp.getXsize(ID),xmp.getYsize(ID)); 272 break; 273 case "16bit": 274 ushort[] raw = xmp.get16bitBitmap(ID); 275 ubyte[] clut = cast(ubyte[])xmp.getPalette(xmp.getPaletteMode(ID)); 276 ubyte[] res2; 277 foreach(c; raw){ 278 ubyte[4] foo = *cast(ubyte[4]*)(clut.ptr + (c*4)); 279 res2 ~= foo; 280 } 281 result = new Bitmap32Bit(res2,xmp.getXsize(ID),xmp.getYsize(ID)); 282 break; 283 case "8bit": 284 ubyte[] raw = xmp.get8bitBitmap(ID); 285 ubyte[] clut = cast(ubyte[])xmp.getPalette(xmp.getPaletteMode(ID)); 286 //writeln(clut); 287 ubyte[] res2; 288 foreach(c; raw){ 289 ubyte[4] foo = *cast(ubyte[4]*)(clut.ptr + (c*4)); 290 writeln(foo); 291 res2 ~= foo; 292 } 293 result = new Bitmap32Bit(res2,xmp.getXsize(ID),xmp.getYsize(ID)); 294 break; 295 default: break; 296 } 297 return result; 298 } 299 300 enum LookupMethod : uint{ 301 NearestValue = 1, 302 Dithering = 2 303 }