bool M_loadSound(const char * filename, void * data) { SF_VIRTUAL_IO io; io.get_filelen = &M_SFGetFileLen; io.seek = &M_SFSeek; io.read = &M_SFRead; io.write = &M_SFWrite; io.tell = &M_SFTell; // open file SF_INFO infos; MFile* File = M_fopen(filename, "rb"); SNDFILE * file = sf_open_virtual(&io, SFM_READ, &infos, File); if(! file){ M_fclose(File); printf("ERROR Load Sound : unable to read %s file\n", filename); return false; } int nbSamples = infos.channels * (int)infos.frames; int sampleRate = infos.samplerate; M_SOUND_FORMAT format; switch(infos.channels) { case 1 : format = M_SOUND_FORMAT_MONO16; break; case 2 : format = M_SOUND_FORMAT_STEREO16; break; default : printf("ERROR Load Sound : non supported format\n"); M_fclose(File); return false; } MSound * sound = (MSound *)data; unsigned int size = nbSamples*2; sound->create(format, size, (unsigned int)sampleRate); // 16 bits file reading if(sf_read_short(file, (short*)sound->getData(), nbSamples) < nbSamples) { printf("ERROR Load Sound : unable to read samples\n"); M_fclose(File); return false; } sf_close(file); M_fclose(File); return true; }
// Materials anim bin export bool exportMaterialsAnimBin(const char * filename, MMaterialsAnim * anim) { int version = 1; // create file MFile * file = M_fopen(filename, "wb"); if(! file) { printf("Error : can't create file %s\n", filename); return false; } // header M_fwrite(M_MA_HEADER, sizeof(char), 8, file); // version M_fwrite(&version, sizeof(int), 1, file); // materials unsigned int m, materialsAnimNumber = anim->getMaterialsAnimNumber(); MMaterialAnim * materialsAnim = anim->getMaterialsAnim(); M_fwrite(&materialsAnimNumber, sizeof(int), 1, file); for(m=0; m<materialsAnimNumber; m++) { MMaterialAnim * matAnim = &(materialsAnim[m]); unsigned int opacityKeysNumber = matAnim->getOpacityKeysNumber(); unsigned int shininessKeysNumber = matAnim->getShininessKeysNumber(); unsigned int customValueKeysNumber = matAnim->getCustomValueKeysNumber(); unsigned int diffuseKeysNumber = matAnim->getDiffuseKeysNumber(); unsigned int specularKeysNumber = matAnim->getSpecularKeysNumber(); unsigned int emitKeysNumber = matAnim->getEmitKeysNumber(); unsigned int customColorKeysNumber = matAnim->getCustomColorKeysNumber(); MKey * opacityKeys = matAnim->getOpacityKeys(); MKey * shininessKeys = matAnim->getShininessKeys(); MKey * customValueKeys = matAnim->getCustomValueKeys(); MKey * diffuseKeys = matAnim->getDiffuseKeys(); MKey * specularKeys = matAnim->getSpecularKeys(); MKey * emitKeys = matAnim->getEmitKeys(); MKey * customColorKeys = matAnim->getCustomColorKeys(); writeKeys(file, opacityKeys, M_VARIABLE_FLOAT, opacityKeysNumber); writeKeys(file, shininessKeys, M_VARIABLE_FLOAT, shininessKeysNumber); writeKeys(file, customValueKeys, M_VARIABLE_FLOAT, customValueKeysNumber); writeKeys(file, diffuseKeys, M_VARIABLE_VEC3, diffuseKeysNumber); writeKeys(file, specularKeys, M_VARIABLE_VEC3, specularKeysNumber); writeKeys(file, emitKeys, M_VARIABLE_VEC3, emitKeysNumber); writeKeys(file, customColorKeys, M_VARIABLE_VEC3, customColorKeysNumber); } M_fclose(file); return true; }
// Textures anim bin export bool exportTexturesAnimBin(const char * filename, MTexturesAnim * anim) { int version = 1; // create file MFile * file = M_fopen(filename, "wb"); if(! file) { printf("Error : can't create file %s\n", filename); return false; } // header M_fwrite(M_TA_HEADER, sizeof(char), 8, file); // version M_fwrite(&version, sizeof(int), 1, file); // textures unsigned int t, texturesAnimNumber = anim->getTexturesAnimNumber(); MTextureAnim * texturesAnim = anim->getTexturesAnim(); M_fwrite(&texturesAnimNumber, sizeof(int), 1, file); for(t=0; t<texturesAnimNumber; t++) { MTextureAnim * texAnim = &(texturesAnim[t]); unsigned int translateKeysNumber = texAnim->getTranslateKeysNumber(); unsigned int scaleKeysNumber = texAnim->getScaleKeysNumber(); unsigned int rotationKeysNumber = texAnim->getRotationKeysNumber(); MKey * translateKeys = texAnim->getTranslateKeys(); MKey * scaleKeys = texAnim->getScaleKeys(); MKey * rotationKeys = texAnim->getRotationKeys(); writeKeys(file, translateKeys, M_VARIABLE_VEC2, translateKeysNumber); writeKeys(file, scaleKeys, M_VARIABLE_VEC2, scaleKeysNumber); writeKeys(file, rotationKeys, M_VARIABLE_FLOAT, rotationKeysNumber); } M_fclose(file); return true; }
// Armature anim bin export bool exportArmatureAnimBin(const char * filename, MArmatureAnim * anim) { int version = 1; // create file MFile * file = M_fopen(filename, "wb"); if(! file) { printf("Error : can't create file %s\n", filename); return false; } // header M_fwrite(M_AA_HEADER, sizeof(char), 8, file); // version M_fwrite(&version, sizeof(int), 1, file); // bones unsigned int b, bonesAnimNumber = anim->getBonesAnimNumber(); MObject3dAnim * bonesAnim = anim->getBonesAnim(); M_fwrite(&bonesAnimNumber, sizeof(int), 1, file); for(b=0; b<bonesAnimNumber; b++) { MObject3dAnim * objAnim = &(bonesAnim[b]); unsigned int positionKeysNumber = objAnim->getPositionKeysNumber(); unsigned int scaleKeysNumber = objAnim->getScaleKeysNumber(); unsigned int rotationKeysNumber = objAnim->getRotationKeysNumber(); MKey * positionKeys = objAnim->getPositionKeys(); MKey * scaleKeys = objAnim->getScaleKeys(); MKey * rotationKeys = objAnim->getRotationKeys(); writeKeys(file, positionKeys, M_VARIABLE_VEC3, positionKeysNumber); writeKeys(file, scaleKeys, M_VARIABLE_VEC3, scaleKeysNumber); writeKeys(file, rotationKeys, M_VARIABLE_QUAT, rotationKeysNumber); } M_fclose(file); return true; }
// Mesh bin export bool exportMeshBin(const char * filename, MMesh * mesh) { int version = 2; char rep[256]; bool state; // create file MFile * file = M_fopen(filename, "wb"); if(! file) { printf("Error : can't create file %s\n", filename); return false; } // get file directory getRepertory(rep, filename); // header M_fwrite(M_MESH_HEADER, sizeof(char), 8, file); // version M_fwrite(&version, sizeof(int), 1, file); // Animation { // anim refs MArmatureAnimRef * armatureAnimRef = mesh->getArmatureAnimRef(); MTexturesAnimRef * texturesAnimRef = mesh->getTexturesAnimRef(); MMaterialsAnimRef * materialsAnimRef = mesh->getMaterialsAnimRef(); // armature anim ref writeDataRef(file, armatureAnimRef, rep); // textures anim ref writeDataRef(file, texturesAnimRef, rep); // materials anim ref writeDataRef(file, materialsAnimRef, rep); // anims ranges unsigned int animsRangesNumber = mesh->getAnimsRangesNumber(); MAnimRange * animsRanges = mesh->getAnimsRanges(); M_fwrite(&animsRangesNumber, sizeof(int), 1, file); if(animsRangesNumber > 0) M_fwrite(animsRanges, sizeof(MAnimRange), animsRangesNumber, file); } // Textures { unsigned int t, texturesNumber = mesh->getTexturesNumber(); M_fwrite(&texturesNumber, sizeof(int), 1, file); for(t=0; t<texturesNumber; t++) { MTexture * texture = mesh->getTexture(t); MTextureRef * textureRef = texture->getTextureRef(); M_TEX_GEN_MODES genMode = texture->getGenMode(); M_WRAP_MODES UWrapMode = texture->getUWrapMode(); M_WRAP_MODES VWrapMode = texture->getVWrapMode(); MVector2 texTranslate = texture->getTexTranslate(); MVector2 texScale = texture->getTexScale(); float texRotate = texture->getTexRotate(); // texture ref writeDataRef(file, textureRef, rep); if(textureRef) { bool mipmap = textureRef->isMipmapEnabled(); M_fwrite(&mipmap, sizeof(bool), 1, file); } // data M_fwrite(&genMode, sizeof(M_TEX_GEN_MODES), 1, file); M_fwrite(&UWrapMode, sizeof(M_WRAP_MODES), 1, file); M_fwrite(&VWrapMode, sizeof(M_WRAP_MODES), 1, file); M_fwrite(&texTranslate, sizeof(MVector2), 1, file); M_fwrite(&texScale, sizeof(MVector2), 1, file); M_fwrite(&texRotate, sizeof(float), 1, file); } } // Materials { unsigned int m, materialsNumber = mesh->getMaterialsNumber(); M_fwrite(&materialsNumber, sizeof(int), 1, file); for(m=0; m<materialsNumber; m++) { MMaterial * material = mesh->getMaterial(m); int type = material->getType(); float opacity = material->getOpacity(); float shininess = material->getShininess(); float customValue = material->getCustomValue(); M_BLENDING_MODES blendMode = material->getBlendMode(); MVector3 emit = material->getEmit(); MVector3 diffuse = material->getDiffuse(); MVector3 specular = material->getSpecular(); MVector3 customColor = material->getCustomColor(); MFXRef * FXRef = material->getFXRef(); MFXRef * ZFXRef = material->getZFXRef(); // FX ref state = FXRef != NULL; M_fwrite(&state, sizeof(bool), 1, file); if(FXRef) { MShaderRef * vertShadRef = FXRef->getVertexShaderRef(); MShaderRef * pixShadRef = FXRef->getPixelShaderRef(); writeDataRef(file, vertShadRef, rep); writeDataRef(file, pixShadRef, rep); } // Z FX ref state = ZFXRef != NULL; M_fwrite(&state, sizeof(bool), 1, file); if(ZFXRef) { MShaderRef * vertShadRef = ZFXRef->getVertexShaderRef(); MShaderRef * pixShadRef = ZFXRef->getPixelShaderRef(); writeDataRef(file, vertShadRef, rep); writeDataRef(file, pixShadRef, rep); } // data M_fwrite(&type, sizeof(int), 1, file); M_fwrite(&opacity, sizeof(float), 1, file); M_fwrite(&shininess, sizeof(float), 1, file); M_fwrite(&customValue, sizeof(float), 1, file); M_fwrite(&blendMode, sizeof(M_BLENDING_MODES), 1, file); M_fwrite(&emit, sizeof(MVector3), 1, file); M_fwrite(&diffuse, sizeof(MVector3), 1, file); M_fwrite(&specular, sizeof(MVector3), 1, file); M_fwrite(&customColor, sizeof(MVector3), 1, file); // textures pass unsigned int t, texturesPassNumber = material->getTexturesPassNumber(); M_fwrite(&texturesPassNumber, sizeof(int), 1, file); for(t=0; t<texturesPassNumber; t++) { MTexturePass * texturePass = material->getTexturePass(t); MTexture * texture = texturePass->getTexture(); unsigned int mapChannel = texturePass->getMapChannel(); M_TEX_COMBINE_MODES combineMode = texturePass->getCombineMode(); // texture id int textureId = getTextureId(mesh, texture); M_fwrite(&textureId, sizeof(int), 1, file); // data M_fwrite(&mapChannel, sizeof(int), 1, file); M_fwrite(&combineMode, sizeof(M_TEX_COMBINE_MODES), 1, file); } } } // Bones { MArmature * armature = mesh->getArmature(); state = armature != NULL; M_fwrite(&state, sizeof(bool), 1, file); if(armature) { unsigned int b, bonesNumber = armature->getBonesNumber(); M_fwrite(&bonesNumber, sizeof(int), 1, file); for(b=0; b<bonesNumber; b++) { MOBone * bone = armature->getBone(b); MObject3d * parent = bone->getParent(); MVector3 position = bone->getPosition(); MVector3 scale = bone->getScale(); MQuaternion rotation = bone->getRotation(); // name writeString(file, bone->getName()); // parent id int parentId = -1; if(parent) { unsigned int id; if(armature->getBoneId(parent->getName(), &id)) parentId = (int)id; } M_fwrite(&parentId, sizeof(int), 1, file); // position / rotation / scale M_fwrite(&position, sizeof(MVector3), 1, file); M_fwrite(&rotation, sizeof(MQuaternion), 1, file); M_fwrite(&scale, sizeof(MVector3), 1, file); } } } // BoundingBox { MBox3d * box = mesh->getBoundingBox(); M_fwrite(box, sizeof(MBox3d), 1, file); } // SubMeshs { unsigned int s, subMeshsNumber = mesh->getSubMeshsNumber(); MSubMesh * subMeshs = mesh->getSubMeshs(); M_fwrite(&subMeshsNumber, sizeof(int), 1, file); for(s=0; s<subMeshsNumber; s++) { MSubMesh * subMesh = &(subMeshs[s]); unsigned int indicesSize = subMesh->getIndicesSize(); unsigned int verticesSize = subMesh->getVerticesSize(); unsigned int normalsSize = subMesh->getNormalsSize(); unsigned int tangentsSize = subMesh->getTangentsSize(); unsigned int texCoordsSize = subMesh->getTexCoordsSize(); unsigned int colorsSize = subMesh->getColorsSize(); M_TYPES indicesType = subMesh->getIndicesType(); void * indices = subMesh->getIndices(); MColor * colors = subMesh->getColors(); MVector3 * vertices = subMesh->getVertices(); MVector3 * normals = subMesh->getNormals(); MVector3 * tangents = subMesh->getTangents(); MVector2 * texCoords = subMesh->getTexCoords(); MBox3d * box = subMesh->getBoundingBox(); MSkinData * skin = subMesh->getSkinData(); map<unsigned int, unsigned int> * mapChannelOffsets = subMesh->getMapChannelOffsets(); // BoundingBox M_fwrite(box, sizeof(MBox3d), 1, file); // indices M_fwrite(&indicesSize, sizeof(int), 1, file); if(indicesSize > 0) { // indice type M_fwrite(&indicesType, sizeof(M_TYPES), 1, file); switch(indicesType) { case M_USHORT: M_fwrite(indices, sizeof(short), indicesSize, file); break; case M_UINT: M_fwrite(indices, sizeof(int), indicesSize, file); break; } } // vertices M_fwrite(&verticesSize, sizeof(int), 1, file); if(verticesSize > 0) M_fwrite(vertices, sizeof(MVector3), verticesSize, file); // normals M_fwrite(&normalsSize, sizeof(int), 1, file); if(normalsSize > 0) M_fwrite(normals, sizeof(MVector3), normalsSize, file); // tangents M_fwrite(&tangentsSize, sizeof(int), 1, file); if(tangentsSize > 0) M_fwrite(tangents, sizeof(MVector3), tangentsSize, file); // texCoords M_fwrite(&texCoordsSize, sizeof(int), 1, file); if(texCoordsSize > 0) M_fwrite(texCoords, sizeof(MVector2), texCoordsSize, file); // colors M_fwrite(&colorsSize, sizeof(int), 1, file); if(colorsSize > 0) M_fwrite(colors, sizeof(MColor), colorsSize, file); // mapChannels { unsigned int size = mapChannelOffsets->size(); M_fwrite(&size, sizeof(int), 1, file); map<unsigned int, unsigned int>::iterator mit (mapChannelOffsets->begin()), mend(mapChannelOffsets->end()); for(;mit!=mend;++mit) { M_fwrite(&mit->first, sizeof(int), 1, file); M_fwrite(&mit->second, sizeof(int), 1, file); } } // Skins state = skin != NULL; M_fwrite(&state, sizeof(bool), 1, file); if(skin) { // skin point unsigned int p, pointsNumber = skin->getPointsNumber(); M_fwrite(&pointsNumber, sizeof(int), 1, file); for(p=0; p<pointsNumber; p++) { MSkinPoint * skinPoint = skin->getPoint(p); unsigned int vertexId = skinPoint->getVertexId(); unsigned int bonesNumber = skinPoint->getBonesNumber(); unsigned short * bonesIds = skinPoint->getBonesIds(); float * bonesWeights = skinPoint->getBonesWeights(); // data M_fwrite(&vertexId, sizeof(int), 1, file); M_fwrite(&bonesNumber, sizeof(int), 1, file); if(bonesNumber > 0) { M_fwrite(bonesIds, sizeof(short), bonesNumber, file); M_fwrite(bonesWeights, sizeof(float), bonesNumber, file); } } } // Displays unsigned int d, displaysNumber = subMesh->getDisplaysNumber(); M_fwrite(&displaysNumber, sizeof(int), 1, file); for(d=0; d<displaysNumber; d++) { MDisplay * display = subMesh->getDisplay(d); M_PRIMITIVE_TYPES primitiveType = display->getPrimitiveType(); unsigned int begin = display->getBegin(); unsigned int size = display->getSize(); MMaterial * material = display->getMaterial(); M_CULL_MODES cullMode = display->getCullMode(); int materialId = getMaterialId(mesh, material); // data M_fwrite(&primitiveType, sizeof(M_PRIMITIVE_TYPES), 1, file); M_fwrite(&begin, sizeof(int), 1, file); M_fwrite(&size, sizeof(int), 1, file); M_fwrite(&materialId, sizeof(int), 1, file); M_fwrite(&cullMode, sizeof(M_CULL_MODES), 1, file); } } } M_fclose(file); return true; }
bool M_loadWavSound(const char * filename, void * data) { MFile * file = M_fopen(filename, "rb"); if(! file) { printf("ERROR Load Sound : unable to read %s file\n", filename); return false; } // read header char header[4]; M_fread(header, sizeof(char), 4, file); // RIFF - WAV if(strncmp(header, "RIFF", 4) == 0) { unsigned int size; M_fread(&size, sizeof(int), 1, file); M_fread(header, sizeof(char), 4, file); if(strncmp(header, "WAVE", 4) == 0) { short format_tag, channels, block_align, bits_per_sample; unsigned int format_length, sample_rate, avg_bytes_sec, data_size; M_fread(header, sizeof(char), 4, file); // "fmt "; M_fread(&format_length, sizeof(int),1,file); M_fread(&format_tag, sizeof(short), 1, file); M_fread(&channels, sizeof(short),1,file); M_fread(&sample_rate, sizeof(int), 1, file); M_fread(&avg_bytes_sec, sizeof(int), 1, file); M_fread(&block_align, sizeof(short), 1, file); M_fread(&bits_per_sample, sizeof(short), 1, file); M_fread(header, sizeof(char), 4, file); // "data" M_fread(&data_size, sizeof(int), 1, file); if((! (bits_per_sample == 8 || bits_per_sample == 16)) || (! (channels > 0 && channels <= 2)) || (format_tag != 1)) { printf("1ERROR Load Sound : unsupported RIFF file\n"); M_fclose(file); return false; } M_SOUND_FORMAT format; switch(bits_per_sample) { case 8: { switch(channels) { case 1: format = M_SOUND_FORMAT_MONO8; break; case 2: format = M_SOUND_FORMAT_STEREO8; break; } break; } case 16: { switch(channels) { case 1: format = M_SOUND_FORMAT_MONO16; break; case 2: format = M_SOUND_FORMAT_STEREO16; break; } break; } } // create sound MSound * sound = (MSound *)data; sound->create(format, data_size, sample_rate); // read sound data M_fread((char *)sound->getData(), sizeof(char), data_size, file); M_fclose(file); return true; } else{ printf("ERROR Load Sound : unsupported RIFF file\n"); } } M_fclose(file); return false; }
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; }