bool M_saveImage(const char * filename, void * data, unsigned int quality) { DevILInit(); ILuint ImgId = 0; ilGenImages(1, &ImgId); // bind this image name. ilBindImage(ImgId); MImage * image = (MImage *)data; unsigned int width = image->getWidth(); unsigned int height = image->getHeight(); unsigned int components = image->getComponents(); if(components == 3) ilTexImage(width, height, 1, 3, IL_RGB, IL_UNSIGNED_BYTE, image->getData()); else if(components == 4) ilTexImage(width, height, 1, 4, IL_RGBA, IL_UNSIGNED_BYTE, image->getData()); iluFlipImage(); if(quality < 100) ilSetInteger(IL_JPG_QUALITY, quality); ilEnable(IL_FILE_OVERWRITE); ilSaveImage(filename); ilDeleteImages(1, &ImgId); DevILShutDown(); return true; }
bool M_loadImage(const char * filename, void * data) { DevILInit(); // gen image ILuint ImgId = 0; ilGenImages(1, &ImgId); // bind image ilBindImage(ImgId); // load image if(! ilLoadImage(filename)) { ilDeleteImages(1, &ImgId); DevILShutDown(); return false; } // get properties int bytePerPix = ilGetInteger(IL_IMAGE_BYTES_PER_PIXEL); int width = ilGetInteger(IL_IMAGE_WIDTH); int height = ilGetInteger(IL_IMAGE_HEIGHT); if(bytePerPix == 4) ilConvertImage(IL_RGBA, IL_UNSIGNED_BYTE); else ilConvertImage(IL_RGB, IL_UNSIGNED_BYTE); // create image MImage * image = (MImage *)data; image->create(M_UBYTE, (unsigned int)width, (unsigned int)height, (unsigned int)bytePerPix); // copy data unsigned int size = image->getSize(); memcpy(image->getData(), ilGetData(), size); ilDeleteImages(1, &ImgId); DevILShutDown(); return true; }
bool M_loadFont(const char * filename, void * data, void * arg) { MFont * font = (MFont *)data; int pen_x, pen_y, max_y; unsigned int n, max_code = 4096; unsigned int size = font->getFontSize(); unsigned int space = 2; unsigned int width = 1024; unsigned int height = 0; MImage image; FT_GlyphSlot slot; FT_Library library; FT_Face face; FT_Byte * file_base; FT_Long file_size; // init FT_Error error = FT_Init_FreeType(&library); if(error){ printf("ERROR Load Font : unable to init FreeType\n"); return false; } // open file MFile * file = M_fopen(filename, "rb"); if(! file) { FT_Done_FreeType(library); printf("ERROR Load Font : can't read file %s\n", filename); return false; } M_fseek(file, 0, SEEK_END); file_size = M_ftell(file); M_rewind(file); file_base = new FT_Byte[file_size]; if(file_size != M_fread(file_base, sizeof(FT_Byte), file_size, file)) { M_fclose(file); FT_Done_FreeType(library); delete [] file_base; return false; } // read font error = FT_New_Memory_Face(library, file_base, file_size, 0, &face); M_fclose(file); if(error) { printf("ERROR Load Font : unable to read data %s\n", filename); FT_Done_FreeType(library); delete [] file_base; return false; } // set font size error = FT_Set_Pixel_Sizes(face, 0, size); if(error) { printf("ERROR Load Font : unable to size font\n"); FT_Done_FreeType(library); delete [] file_base; return false; } // parse characters max_y = 0; slot = face->glyph; pen_x = space; pen_y = space; for(n = 0; n<max_code; n++) { // load glyph image into the slot (erase previous one) error = FT_Load_Char(face, n, FT_LOAD_RENDER | FT_LOAD_NO_HINTING); if(error) continue; if(FT_Get_Char_Index(face, n) == 0) continue; // max y max_y = MAX(max_y, slot->bitmap.rows); if((pen_x + slot->bitmap.width + space) > width) { pen_x = space; pen_y += max_y + space; height += max_y + space; max_y = 0; } // increment pen position pen_x += slot->bitmap.width + space; } if(height == 0) { printf("ERROR Load Font : unable to create font texture\n"); FT_Done_FreeType(library); delete [] file_base; return false; } // create image height = getNextPowerOfTwo(height); image.create(M_UBYTE, width, height, 4); memset(image.getData(), 0, image.getSize()*sizeof(char)); // init font font->setTextureWidth(width); font->setTextureHeight(height); // create font texture max_y = 0; slot = face->glyph; pen_x = space; pen_y = space; for(n = 0; n<max_code; n++) { // load glyph image into the slot (erase previous one) error = FT_Load_Char(face, n, FT_LOAD_RENDER | FT_LOAD_NO_HINTING); if(error) continue; if(FT_Get_Char_Index(face, n) == 0) continue; // max y max_y = MAX(max_y, slot->bitmap.rows); if((pen_x + slot->bitmap.width + space) > (int)image.getWidth()){ pen_x = space; pen_y += max_y + space; } // get character properties float xAdvance = (slot->advance.x >> 6) / ((float)size); MVector2 offset = MVector2((float)slot->bitmap_left - 1, - (float)slot->bitmap_top - 1) / ((float)size); MVector2 pos = MVector2((float)(pen_x-1) / (float)width, (float)(pen_y-1) / (float)height); MVector2 scale = MVector2((float)(slot->bitmap.width+2) / (float)width, (float)(slot->bitmap.rows+2) / (float)height); // set character font->setCharacter(n, MCharacter(xAdvance, offset, pos, scale)); // draw to image drawBitmap(&image, &slot->bitmap, pen_x, pen_y); // increment pen position pen_x += slot->bitmap.width + space; } // send texture MEngine * engine = MEngine().getInstance(); MRenderingContext * render = engine->getRenderingContext(); // gen texture id unsigned int textureId = font->getTextureId(); if(textureId == 0) { render->createTexture(&textureId); font->setTextureId(textureId); } // send texture image render->bindTexture(textureId); render->setTextureUWrapMode(M_WRAP_REPEAT); render->setTextureVWrapMode(M_WRAP_REPEAT); render->sendTextureImage(&image, 0, 1, 0); // finish FT_Done_FreeType(library); delete [] file_base; return true; }
bool M_loadImage(const char * filename, void * data, void * arg) { if(! filename) return false; if(! data) return false; // freeimage io FreeImageIO io; io.read_proc = (FI_ReadProc)readProc; io.write_proc = (FI_WriteProc)writeProc; io.tell_proc = (FI_TellProc)tellProc; io.seek_proc = (FI_SeekProc)seekProc; // read file buffer MFile * fp = M_fopen(filename, "rb"); if(! fp) { printf("Error : can't read file %s\n", filename); return false; } // read freeimage FREE_IMAGE_FORMAT format = FreeImage_GetFileTypeFromHandle(&io, (fi_handle)fp, 0); if(format == FIF_UNKNOWN) { printf("Error : unknow format %s\n", filename); M_fclose(fp); return false; } FIBITMAP * dib = FreeImage_LoadFromHandle(format, &io, (fi_handle)fp); if(! dib) { printf("Error : unknow dib %s\n", filename); M_fclose(fp); return false; } BYTE * bits = FreeImage_GetBits(dib); unsigned int width = FreeImage_GetWidth(dib); unsigned int height = FreeImage_GetHeight(dib); unsigned int bpp = FreeImage_GetBPP(dib); FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(dib); if((bits == 0) || (width == 0) || (height == 0)) { FreeImage_Unload(dib); M_fclose(fp); return false; } // flip FreeImage_FlipVertical(dib); // create image MImage * image = (MImage *)data; switch(image_type) { case FIT_BITMAP: switch(bpp) { case 8: image->create(M_UBYTE, width, height, 1); for(unsigned int y=0; y<height; y++) { unsigned char * dest = (unsigned char *)image->getData() + width*y; bits = FreeImage_GetScanLine(dib, y); memcpy(dest, bits, width*sizeof(char)); } break; case 24: SwapRedBlue32(dib); image->create(M_UBYTE, width, height, 3); for(unsigned int y=0; y<height; y++) { unsigned char * dest = (unsigned char *)image->getData() + width*y*3; bits = FreeImage_GetScanLine(dib, y); memcpy(dest, bits, width*3*sizeof(char)); } break; case 32: SwapRedBlue32(dib); image->create(M_UBYTE, width, height, 4); for(unsigned int y=0; y<height; y++) { unsigned char * dest = (unsigned char *)image->getData() + width*y*4; bits = FreeImage_GetScanLine(dib, y); memcpy(dest, bits, width*4*sizeof(char)); } break; default: break; } break; case FIT_RGB16: image->create(M_USHORT, width, height, 3); for(unsigned int y=0; y<height; y++) { unsigned short * dest = (unsigned short *)image->getData() + width*y*3; bits = FreeImage_GetScanLine(dib, y); memcpy(dest, bits, width*3*sizeof(short)); } break; case FIT_RGBA16: image->create(M_USHORT, width, height, 4); for(unsigned int y=0; y<height; y++) { unsigned short * dest = (unsigned short *)image->getData() + width*y*4; bits = FreeImage_GetScanLine(dib, y); memcpy(dest, bits, width*4*sizeof(short)); } break; case FIT_FLOAT: image->create(M_FLOAT, width, height, 1); for(unsigned int y=0; y<height; y++) { float * dest = (float *)image->getData() + width*y; bits = FreeImage_GetScanLine(dib, y); memcpy(dest, bits, width*sizeof(float)); } break; case FIT_RGBF: image->create(M_FLOAT, width, height, 3); for(unsigned int y=0; y<height; y++) { float * dest = (float *)image->getData() + width*y*3; bits = FreeImage_GetScanLine(dib, y); memcpy(dest, bits, width*3*sizeof(float)); } break; case FIT_RGBAF: image->create(M_FLOAT, width, height, 4); for(unsigned int y=0; y<height; y++) { float * dest = (float *)image->getData() + width*y*4; bits = FreeImage_GetScanLine(dib, y); memcpy(dest, bits, width*4*sizeof(float)); } break; default: break; } // clean FreeImage_Unload(dib); M_fclose(fp); return true; }
bool M_saveImage(const char * filename, void * data) { if(! filename) return false; if(! data) return false; // format FREE_IMAGE_FORMAT format = FreeImage_GetFIFFromFilename(filename); if(format == FIF_UNKNOWN) { printf("Error freeImage: unknow image format %s\n", filename); return false; } // image MImage * image = (MImage *)data; if(! image->getData()) return false; unsigned int width = image->getWidth(); unsigned int height = image->getHeight(); unsigned int components = image->getComponents(); unsigned int yStep = width*components; FIBITMAP * dib = NULL; if(image->getDataType() == M_UBYTE) { dib = FreeImage_AllocateT(FIT_BITMAP, width, height, components*8); if(dib) { unsigned char * srcBits = (unsigned char *)image->getData(); for(unsigned int y=0; y<height; y++) { BYTE * bits = FreeImage_GetScanLine(dib, y); memcpy(bits, srcBits, yStep*sizeof(char)); srcBits += yStep; } if(components == 3 || components == 4) SwapRedBlue32(dib); } } else if(image->getDataType() == M_FLOAT) { switch(image->getComponents()) { case 1: dib = FreeImage_AllocateT(FIT_FLOAT, image->getWidth(), image->getHeight(), 32); break; case 3: dib = FreeImage_AllocateT(FIT_RGBF, image->getWidth(), image->getHeight(), 3*32); break; case 4: dib = FreeImage_AllocateT(FIT_RGBAF, image->getWidth(), image->getHeight(), 4*32); break; } if(dib) { float * srcBits = (float *)image->getData(); for(unsigned int y=0; y<height; y++) { BYTE * bits = FreeImage_GetScanLine(dib, y); memcpy(bits, srcBits, yStep*sizeof(float)); srcBits += yStep; } } } if(dib) { // flip FreeImage_FlipVertical(dib); // save if(FreeImage_Save(format, dib, filename, PNG_Z_BEST_SPEED)) { FreeImage_Unload(dib); return true; } } return false; }