// Image saver... bit DevilSave(cstrconst filename,nat32 width,nat32 height,nat32 format,nat32 type,void * data,bit overwrite) { unsigned int handle; ilGenImages(1,(unsigned int *)&handle); ilBindImage(handle); ilEnable(0x0600); ilOriginFunc(0x0601); if (overwrite) ilEnable(DEVIL_FILE_SQUISH); else ilDisable(DEVIL_FILE_SQUISH); int num; switch (format) { case DEVIL_FORM_RGB: num = 3; break; case DEVIL_FORM_RGBA: num = 4; break; default: num = 1; break; } ilTexImage(width,height,1,num,format,type,data); ilSaveImage(filename); if (ilGetError()) { ilDeleteImages(1,(unsigned int *)&handle); return false; } else { ilDeleteImages(1,(unsigned int *)&handle); return true; } }
void ofxTexture::DrawString(string text, ofxBitmapFont* font, ofRectangle dest_rect, unsigned char font_size) { if(m_Locked) return; // TODO: implement draw text with boundary float scale; if(font_size == 0) { scale = 1.0f; } else { scale = (float)font_size/font->GetFontSize(); } ofVec2f cursor(dest_rect.x, dest_rect.y); ilDisable(IL_BLIT_BLEND); for (int i = 0; i < text.size(); i++) { ofVec2f draw_region = scale*font->GetRect(text[i]); ILuint character_image = font->GetImageId(text[i]); ILuint dummy = ilGenImage(); ilBindImage(dummy); ilCopyImage(character_image); iluScale(draw_region.x, draw_region.y, 1); ilBindImage(m_ImageId); ilBlit(dummy, cursor.x, cursor.y, 0, 0, 0, 0, draw_region.x, draw_region.y, 1); ilDeleteImage(dummy); cursor.x += draw_region.x; } ilEnable(IL_BLIT_BLEND); }
void SaveTextureToImageFile( uint32 aWidth, uint32 aHeight, GLuint aTexture, std::string aPath, bool aOverwrite ) { //TODO auto_ptr on textures ILuint imageID; // The image name to return. DEVIL_CHECKED_CALL( ilGenImages( 1, &imageID ) ); DEVIL_CHECKED_CALL( ilBindImage( imageID ) ); if ( aOverwrite ) { DEVIL_CHECKED_CALL( ilEnable(IL_FILE_OVERWRITE) ); } else { DEVIL_CHECKED_CALL( ilDisable(IL_FILE_OVERWRITE) ); } DEVIL_CHECKED_CALL( ilTexImage( aWidth, aHeight, 1, 3, IL_RGB, IL_UNSIGNED_BYTE, NULL ) ); ILubyte* data = new ILubyte[ 3 * aWidth * aHeight ]; GL_CHECKED_CALL( glBindTexture( GL_TEXTURE_2D, aTexture ) ); GL_CHECKED_CALL( glGetTexImage( GL_TEXTURE_2D, 0, GL_RGB, GL_UNSIGNED_BYTE, (void*)data ) ); GL_CHECKED_CALL( glBindTexture( GL_TEXTURE_2D, 0 ) ); DEVIL_CHECKED_CALL( ilSetPixels( 0, 0, 0, aWidth, aHeight, 1, IL_RGB, IL_UNSIGNED_BYTE, data ) ); delete [] data; DEVIL_CHECKED_CALL( ilSaveImage( aPath.data() ) ); DEVIL_CHECKED_CALL( ilDeleteImages( 1, &imageID) ); }
void ofxTexture::BlockTransfer(ofxTexture* source, ofRectangle source_rect, ofVec2f dest_pos, int alpha) { if(m_Locked || source->IsLocked()) return; ilBindImage(m_ImageId); ilDisable(IL_BLIT_BLEND); ilBlit(source->GetDevilId(), dest_pos.x, dest_pos.y, 0, source_rect.x, source_rect.y, 0, source_rect.width, source_rect.height, 1); ilEnable(IL_BLIT_BLEND); }
void ofxTexture::Fill(ofFloatColor color, ofRectangle dest_rect) { if(m_Locked) return; ILuint dummy = ilGenImage(); ilBindImage(dummy); ilTexImage(dest_rect.width, dest_rect.height, 0, 4, IL_RGBA , IL_UNSIGNED_BYTE, NULL); ilClearColour(color.r, color.g, color.b, color.a); ilClearImage(); ilBindImage(m_ImageId); ilDisable(IL_BLIT_BLEND); ilBlit(dummy, dest_rect.x, dest_rect.y, 0, 0, 0, 0, dest_rect.width, dest_rect.height, 1); ilEnable(IL_BLIT_BLEND); ilDeleteImage(dummy); }
void ofxTexture::StretchTransfer(ofxTexture* source, ofRectangle source_rect, ofRectangle dest_rect, int alpha) { if(m_Locked || source->IsLocked()) return; ILuint dummy = ilGenImage(); ilBindImage(dummy); ilCopyImage(source->GetDevilId()); iluScale(dest_rect.width, dest_rect.height, 1); ilBindImage(m_ImageId); ilDisable(IL_BLIT_BLEND); ilBlit(dummy, dest_rect.x, dest_rect.y, 0, source_rect.x, source_rect.y, 0, source_rect.width, source_rect.height, 1); ilEnable(IL_BLIT_BLEND); ilDeleteImage(dummy); }
bool CBitmap::Save(std::string const& filename, bool opaque) const { if (type == BitmapTypeDDS) { #ifndef BITMAP_NO_OPENGL return ddsimage->save(filename); #else return false; #endif // !BITMAP_NO_OPENGL } unsigned char* buf = new unsigned char[xsize * ysize * 4]; const int ymax = (ysize - 1); /* HACK Flip the image so it saves the right way up. (Fiddling with ilOriginFunc didn't do anything?) Duplicated with ReverseYAxis. */ for (int y = 0; y < ysize; ++y) { for (int x = 0; x < xsize; ++x) { const int bi = 4 * (x + (xsize * (ymax - y))); const int mi = 4 * (x + (xsize * (y))); buf[bi + 0] = mem[mi + 0]; buf[bi + 1] = mem[mi + 1]; buf[bi + 2] = mem[mi + 2]; buf[bi + 3] = opaque ? 0xff : mem[mi + 3]; } } boost::mutex::scoped_lock lck(devilMutex); ilOriginFunc(IL_ORIGIN_UPPER_LEFT); ilEnable(IL_ORIGIN_SET); ilHint(IL_COMPRESSION_HINT, IL_USE_COMPRESSION); ilSetInteger(IL_JPG_QUALITY, 80); ILuint ImageName = 0; ilGenImages(1, &ImageName); ilBindImage(ImageName); ilTexImage(xsize, ysize, 1, 4, IL_RGBA, IL_UNSIGNED_BYTE, buf); const std::string fullpath = dataDirsAccess.LocateFile(filename, FileQueryFlags::WRITE); const bool success = ilSaveImage((char*)fullpath.c_str()); ilDeleteImages(1, &ImageName); ilDisable(IL_ORIGIN_SET); delete[] buf; return success; }
bool CBitmap::LoadGrayscale(const std::string& filename) { type = BitmapTypeStandardAlpha; channels = 1; CFileHandler file(filename); if (!file.FileExists()) { return false; } unsigned char* buffer = new unsigned char[file.FileSize() + 1]; file.Read(buffer, file.FileSize()); boost::mutex::scoped_lock lck(devilMutex); ilOriginFunc(IL_ORIGIN_UPPER_LEFT); ilEnable(IL_ORIGIN_SET); ILuint ImageName = 0; ilGenImages(1, &ImageName); ilBindImage(ImageName); const bool success = !!ilLoadL(IL_TYPE_UNKNOWN, buffer, file.FileSize()); ilDisable(IL_ORIGIN_SET); delete[] buffer; if (success == false) { return false; } ilConvertImage(IL_LUMINANCE, IL_UNSIGNED_BYTE); xsize = ilGetInteger(IL_IMAGE_WIDTH); ysize = ilGetInteger(IL_IMAGE_HEIGHT); delete[] mem; mem = NULL; // to prevent a dead-pointer in case of an out-of-memory exception on the next line mem = new unsigned char[xsize * ysize]; memcpy(mem, ilGetData(), xsize * ysize); ilDeleteImages(1, &ImageName); return true; }
bool CBitmap::Load(std::string const& filename, unsigned char defaultAlpha) { #ifndef BITMAP_NO_OPENGL ScopedTimer timer("Textures::CBitmap::Load"); #endif bool noAlpha = true; delete[] mem; mem = NULL; #ifndef BITMAP_NO_OPENGL textype = GL_TEXTURE_2D; #endif // !BITMAP_NO_OPENGL if (filename.find(".dds") != std::string::npos) { #ifndef BITMAP_NO_OPENGL type = BitmapTypeDDS; xsize = 0; ysize = 0; channels = 0; ddsimage = new nv_dds::CDDSImage(); bool status = ddsimage->load(filename); if (status) { xsize = ddsimage->get_width(); ysize = ddsimage->get_height(); channels = ddsimage->get_components(); switch (ddsimage->get_type()) { case nv_dds::TextureFlat : textype = GL_TEXTURE_2D; break; case nv_dds::Texture3D : textype = GL_TEXTURE_3D; break; case nv_dds::TextureCubemap : textype = GL_TEXTURE_CUBE_MAP; break; case nv_dds::TextureNone : default : break; } } return status; #else // !BITMAP_NO_OPENGL AllocDummy(); //allocate a dummy texture, as dds aren't supported in headless return true; #endif // !BITMAP_NO_OPENGL } type = BitmapTypeStandardRGBA; channels = 4; CFileHandler file(filename); if (file.FileExists() == false) { AllocDummy(); return false; } unsigned char* buffer = new unsigned char[file.FileSize() + 2]; file.Read(buffer, file.FileSize()); boost::mutex::scoped_lock lck(devilMutex); ilOriginFunc(IL_ORIGIN_UPPER_LEFT); ilEnable(IL_ORIGIN_SET); ILuint ImageName = 0; ilGenImages(1, &ImageName); ilBindImage(ImageName); { // do not signal floating point exceptions in devil library ScopedDisableFpuExceptions fe; const bool success = !!ilLoadL(IL_TYPE_UNKNOWN, buffer, file.FileSize()); ilDisable(IL_ORIGIN_SET); delete[] buffer; if (success == false) { AllocDummy(); return false; } } noAlpha = (ilGetInteger(IL_IMAGE_BYTES_PER_PIXEL) != 4); ilConvertImage(IL_RGBA, IL_UNSIGNED_BYTE); xsize = ilGetInteger(IL_IMAGE_WIDTH); ysize = ilGetInteger(IL_IMAGE_HEIGHT); mem = new unsigned char[xsize * ysize * 4]; //ilCopyPixels(0, 0, 0, xsize, ysize, 0, IL_RGBA, IL_UNSIGNED_BYTE, mem); memcpy(mem, ilGetData(), xsize * ysize * 4); ilDeleteImages(1, &ImageName); if (noAlpha) { for (int y=0; y < ysize; ++y) { for (int x=0; x < xsize; ++x) { mem[((y*xsize+x) * 4) + 3] = defaultAlpha; } } } return true; }
// // ILSTATE // ILboolean ilState::Disable(ILenum State) { return ilDisable(State); }
bool CBitmap::Load(std::string const& filename, unsigned char defaultAlpha) { bool noAlpha = true; delete[] mem; mem = NULL; #ifndef BITMAP_NO_OPENGL textype = GL_TEXTURE_2D; #endif // !BITMAP_NO_OPENGL if (filename.find(".dds") != std::string::npos) { type = BitmapTypeDDS; xsize = 0; ysize = 0; channels = 0; #ifndef BITMAP_NO_OPENGL ddsimage = new nv_dds::CDDSImage(); bool status = ddsimage->load(filename); if (status) { xsize = ddsimage->get_width(); ysize = ddsimage->get_height(); channels = ddsimage->get_components(); switch (ddsimage->get_type()) { case nv_dds::TextureFlat : textype = GL_TEXTURE_2D; break; case nv_dds::Texture3D : textype = GL_TEXTURE_3D; break; case nv_dds::TextureCubemap : textype = GL_TEXTURE_CUBE_MAP; break; case nv_dds::TextureNone : default : break; } } return status; #else return false; #endif // !BITMAP_NO_OPENGL } type = BitmapTypeStandardRGBA; channels = 4; CFileHandler file(filename); if (file.FileExists() == false) { Alloc(1, 1); return false; } unsigned char* buffer = new unsigned char[file.FileSize() + 2]; file.Read(buffer, file.FileSize()); boost::mutex::scoped_lock lck(devilMutex); ilOriginFunc(IL_ORIGIN_UPPER_LEFT); ilEnable(IL_ORIGIN_SET); ILuint ImageName = 0; ilGenImages(1, &ImageName); ilBindImage(ImageName); const bool success = !!ilLoadL(IL_TYPE_UNKNOWN, buffer, file.FileSize()); ilDisable(IL_ORIGIN_SET); delete[] buffer; if (success == false) { xsize = 1; ysize = 1; mem = new unsigned char[4]; mem[0] = 255; // Red allows us to easily see textures that failed to load mem[1] = 0; mem[2] = 0; mem[3] = 255; // Non Transparent return false; } noAlpha = (ilGetInteger(IL_IMAGE_BYTES_PER_PIXEL) != 4); ilConvertImage(IL_RGBA, IL_UNSIGNED_BYTE); xsize = ilGetInteger(IL_IMAGE_WIDTH); ysize = ilGetInteger(IL_IMAGE_HEIGHT); mem = new unsigned char[xsize * ysize * 4]; //ilCopyPixels(0, 0, 0, xsize, ysize, 0, IL_RGBA, IL_UNSIGNED_BYTE, mem); memcpy(mem, ilGetData(), xsize * ysize * 4); ilDeleteImages(1, &ImageName); if (noAlpha) { for (int y=0; y < ysize; ++y) { for (int x=0; x < xsize; ++x) { mem[((y*xsize+x) * 4) + 3] = defaultAlpha; } } } return true; }
//--------------------------------------------------------------------- Codec::DecodeResult ILImageCodec::decode(DataStreamPtr& input) const { // DevIL variables ILuint ImageName; ILint ImageFormat, BytesPerPixel, ImageType; ImageData* imgData = new ImageData(); MemoryDataStreamPtr output; // Load the image ilGenImages( 1, &ImageName ); ilBindImage( ImageName ); // Put it right side up ilEnable(IL_ORIGIN_SET); ilSetInteger(IL_ORIGIN_MODE, IL_ORIGIN_UPPER_LEFT); // Keep DXTC(compressed) data if present ilSetInteger(IL_KEEP_DXTC_DATA, IL_TRUE); // Load image from stream, cache into memory MemoryDataStream memInput(input); ilLoadL( mIlType, memInput.getPtr(), static_cast< ILuint >(memInput.size())); // Check if everything was ok ILenum PossibleError = ilGetError() ; if( PossibleError != IL_NO_ERROR ) { OGRE_EXCEPT( Exception::ERR_NOT_IMPLEMENTED, "IL Error", iluErrorString(PossibleError) ) ; } ImageFormat = ilGetInteger( IL_IMAGE_FORMAT ); ImageType = ilGetInteger( IL_IMAGE_TYPE ); // Convert image if ImageType is incompatible with us (double or long) if(ImageType != IL_BYTE && ImageType != IL_UNSIGNED_BYTE && ImageType != IL_FLOAT && ImageType != IL_UNSIGNED_SHORT && ImageType != IL_SHORT) { ilConvertImage(ImageFormat, IL_FLOAT); ImageType = IL_FLOAT; } // Converted paletted images if(ImageFormat == IL_COLOUR_INDEX) { ilConvertImage(IL_BGRA, IL_UNSIGNED_BYTE); ImageFormat = IL_BGRA; ImageType = IL_UNSIGNED_BYTE; } // Now sets some variables BytesPerPixel = ilGetInteger( IL_IMAGE_BYTES_PER_PIXEL ); imgData->format = ILUtil::ilFormat2OgreFormat( ImageFormat, ImageType ); imgData->width = ilGetInteger( IL_IMAGE_WIDTH ); imgData->height = ilGetInteger( IL_IMAGE_HEIGHT ); imgData->depth = ilGetInteger( IL_IMAGE_DEPTH ); imgData->num_mipmaps = ilGetInteger ( IL_NUM_MIPMAPS ); imgData->flags = 0; if(imgData->format == PF_UNKNOWN) { std::stringstream err; err << "Unsupported devil format ImageFormat=" << std::hex << ImageFormat << " ImageType="<< ImageType << std::dec; ilDeleteImages( 1, &ImageName ); OGRE_EXCEPT( Exception::ERR_NOT_IMPLEMENTED, err.str(), "ILImageCodec::decode" ) ; } // Check for cubemap //ILuint cubeflags = ilGetInteger ( IL_IMAGE_CUBEFLAGS ); size_t numFaces = ilGetInteger ( IL_NUM_IMAGES ) + 1; if(numFaces == 6) imgData->flags |= IF_CUBEMAP; else numFaces = 1; // Support only 1 or 6 face images for now // Keep DXT data (if present at all and the GPU supports it) ILuint dxtFormat = ilGetInteger( IL_DXTC_DATA_FORMAT ); if(dxtFormat != IL_DXT_NO_COMP && Root::getSingleton().getRenderSystem()->getCapabilities()->hasCapability( RSC_TEXTURE_COMPRESSION_DXT )) { imgData->format = ILUtil::ilFormat2OgreFormat( dxtFormat, ImageType ); imgData->flags |= IF_COMPRESSED; // Validate that this devil version saves DXT mipmaps if(imgData->num_mipmaps>0) { ilBindImage(ImageName); ilActiveMipmap(1); if((size_t)ilGetInteger( IL_DXTC_DATA_FORMAT ) != dxtFormat) { imgData->num_mipmaps=0; LogManager::getSingleton().logMessage( "Warning: Custom mipmaps for compressed image "+input->getName()+" were ignored because they are not loaded by this DevIL version"); } } } // Calculate total size from number of mipmaps, faces and size imgData->size = Image::calculateSize(imgData->num_mipmaps, numFaces, imgData->width, imgData->height, imgData->depth, imgData->format); // Bind output buffer output.bind(new MemoryDataStream(imgData->size)); size_t offset = 0; // Dimensions of current mipmap size_t width = imgData->width; size_t height = imgData->height; size_t depth = imgData->depth; // Transfer data for(size_t mip=0; mip<=imgData->num_mipmaps; ++mip) { for(size_t i = 0; i < numFaces; ++i) { ilBindImage(ImageName); if(numFaces > 1) ilActiveImage(i); if(imgData->num_mipmaps > 0) ilActiveMipmap(mip); /// Size of this face size_t imageSize = PixelUtil::getMemorySize( width, height, depth, imgData->format); if(imgData->flags & IF_COMPRESSED) { // Compare DXT size returned by DevIL with our idea of the compressed size if(imageSize == ilGetDXTCData(NULL, 0, dxtFormat)) { // Retrieve data from DevIL ilGetDXTCData((unsigned char*)output->getPtr()+offset, imageSize, dxtFormat); } else { LogManager::getSingleton().logMessage( "Warning: compressed image "+input->getName()+" size mismatch, devilsize="+StringConverter::toString(ilGetDXTCData(NULL, 0, dxtFormat))+" oursize="+ StringConverter::toString(imageSize)); } } else { /// Retrieve data from DevIL PixelBox dst(width, height, depth, imgData->format, (unsigned char*)output->getPtr()+offset); ILUtil::toOgre(dst); } offset += imageSize; } /// Next mip if(width!=1) width /= 2; if(height!=1) height /= 2; if(depth!=1) depth /= 2; } // Restore IL state ilDisable(IL_ORIGIN_SET); ilDisable(IL_FORMAT_SET); ilDeleteImages( 1, &ImageName ); DecodeResult ret; ret.first = output; ret.second = CodecDataPtr(imgData); return ret; }
void ilFDisable_(int *RetVal, int *Mode) { *RetVal = ilDisable(*Mode); return; }