Пример #1
0
 unsigned int LoadTexture(const char* a_szTexture, unsigned int a_uiFormat /* = 
GL_RGBA */, unsigned int* a_uiWidth /* = nullptr */, unsigned int* a_uiHeight /* = 
nullptr */, unsigned int* a_uiBPP /* = nullptr*/) 
{ 
 FIBITMAP* pBitmap = nullptr; 
 
 // check the file signature and deduce its format and load it 
 FREE_IMAGE_FORMAT fif = FreeImage_GetFileType(a_szTexture, 0); 
 if (fif != FIF_UNKNOWN && FreeImage_FIFSupportsReading(fif)) 
 { 
 pBitmap = FreeImage_Load(fif, a_szTexture); 
 } 
 
 if (pBitmap == nullptr) 
 { 
 printf("Error: Failed to load image '%s'!\n", a_szTexture); 
 return 0; 
 } 
 
 // optionally get the image width and height 
 if (a_uiWidth != nullptr) 
 *a_uiWidth = FreeImage_GetWidth(pBitmap); 
 if (a_uiHeight != nullptr) 
 *a_uiHeight = FreeImage_GetHeight(pBitmap); 
 
 // force the image to RGBA 
 unsigned int bpp = FreeImage_GetBPP(pBitmap); 
 if( a_uiBPP != nullptr ) 
 *a_uiBPP = bpp/8; 
 
 FREE_IMAGE_COLOR_TYPE fi_colourType = FreeImage_GetColorType(pBitmap); 
 if (fi_colourType != FIC_RGBALPHA ) 
 { 
 FIBITMAP* ndib = FreeImage_ConvertTo32Bits(pBitmap); 
 FreeImage_Unload(pBitmap); 
 pBitmap = ndib; 
 bpp = FreeImage_GetBPP(pBitmap); 
 fi_colourType = FreeImage_GetColorType(pBitmap); 
 } 
 
 // get the pixel data 
 BYTE* pData = FreeImage_GetBits(pBitmap); 
 
 // try to determine data type of file (bytes/floats) 
 FREE_IMAGE_TYPE fit = FreeImage_GetImageType(pBitmap); 
 GLenum eType = (fit == FIT_RGBF || fit == FIT_FLOAT) ? 
 GL_FLOAT:GL_UNSIGNED_BYTE; 
 
 // create GL texture 
 GLuint textureID; 
 glGenTextures( 1, &textureID ); 
 glBindTexture( GL_TEXTURE_2D, textureID ); 
 glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, 
 FreeImage_GetWidth(pBitmap), 
FreeImage_GetHeight(pBitmap), 0, 
a_uiFormat, eType, pData); 

 //CREATING A GL BUFFER
 GLuint VBO;
 glGenBuffers(1, &VBO);
 glBindBuffer( GL_Array_Buffer, VBO);
 
 // specify default filtering and wrapping 
 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); 
 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); 
 // unbind texture 
 glBindTexture( GL_TEXTURE_2D, 0 ); 
 
 // delete data 
 FreeImage_Unload(pBitmap); 
 //DELETING THE GL BUFFER MADE ABOVE
 glDeleteBuffers(1, &VBO);
 
 return textureID; 
}
Пример #2
0
/**
Encode a FIBITMAP to a WebP image
@param hmem Memory output stream, containing on return the encoded image
@param dib The FIBITMAP to encode
@param flags FreeImage save flags
@return Returns TRUE if successfull, returns FALSE otherwise
*/
static BOOL
EncodeImage(FIMEMORY *hmem, FIBITMAP *dib, int flags) {
	WebPPicture picture;	// Input buffer
	WebPConfig config;		// Coding parameters

	BOOL bIsFlipped = FALSE;

	try {
		const unsigned width = FreeImage_GetWidth(dib);
		const unsigned height = FreeImage_GetHeight(dib);
		const unsigned bpp = FreeImage_GetBPP(dib);
		const unsigned pitch = FreeImage_GetPitch(dib);

		// check image type
		FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(dib);

		if( !((image_type == FIT_BITMAP) && ((bpp == 24) || (bpp == 32))) )  {
			throw FI_MSG_ERROR_UNSUPPORTED_FORMAT;
		}

		// check format limits
		if(MAX(width, height) > WEBP_MAX_DIMENSION) {
			FreeImage_OutputMessageProc(s_format_id, "Unsupported image size: width x height = %d x %d", width, height);
			return FALSE;
		}

		// Initialize output I/O
		if(WebPPictureInit(&picture) == 1) {
			picture.writer = WebP_MemoryWriter;
			picture.custom_ptr = hmem;
			picture.width = (int)width;
			picture.height = (int)height;
		} else {
			throw "Couldn't initialize WebPPicture";
		}

		// --- Set encoding parameters ---

		// Initialize encoding parameters to default values
		WebPConfigInit(&config);

		// quality/speed trade-off (0=fast, 6=slower-better)
		config.method = 6;

		if((flags & WEBP_LOSSLESS) == WEBP_LOSSLESS) {
			// lossless encoding
			config.lossless = 1;
			picture.use_argb = 1;
		} else if((flags & 0x7F) > 0) {
			// lossy encoding
			config.lossless = 0;
			// quality is between 1 (smallest file) and 100 (biggest) - default to 75
			config.quality = (float)(flags & 0x7F);
			if(config.quality > 100) {
				config.quality = 100;
			}
		}

		// validate encoding parameters
		if(WebPValidateConfig(&config) == 0) {
			throw "Failed to initialize encoder";
		}

		// --- Perform encoding ---
		
		// Invert dib scanlines
		bIsFlipped = FreeImage_FlipVertical(dib);


		// convert dib buffer to output stream

		const BYTE *bits = FreeImage_GetBits(dib);

#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_BGR
		switch(bpp) {
			case 24:
				WebPPictureImportBGR(&picture, bits, pitch);
				break;
			case 32:
				WebPPictureImportBGRA(&picture, bits, pitch);
				break;
		}
#else
		switch(bpp) {
			case 24:
				WebPPictureImportRGB(&picture, bits, pitch);
				break;
			case 32:
				WebPPictureImportRGBA(&picture, bits, pitch);
				break;
		}

#endif // FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_BGR

		if(!WebPEncode(&config, &picture)) {
			throw "Failed to encode image";
		}

		WebPPictureFree(&picture);

		if(bIsFlipped) {
			// invert dib scanlines
			FreeImage_FlipVertical(dib);
		}

		return TRUE;

	} catch (const char* text) {

		WebPPictureFree(&picture);

		if(bIsFlipped) {
			// invert dib scanlines
			FreeImage_FlipVertical(dib);
		}

		if(NULL != text) {
			FreeImage_OutputMessageProc(s_format_id, text);
		}
	}

	return FALSE;
}
Пример #3
0
void Engine::TextureCube::loadFromFiles(
	const CHAR *posx, const CHAR *negx,
	const CHAR *posy, const CHAR *negy,
	const CHAR *posz, const CHAR *negz)
{
	UINT i;
	FIBITMAP *image[6];
	FIBITMAP *tmp;
	ID3D11Texture2D *texture;

	const CHAR *tex[] = { posx, negx, negy, posy, posz, negz };
	image[0] = FreeImage_Load(FreeImage_GetFileType(tex[0]), tex[0]);
	image[1] = FreeImage_Load(FreeImage_GetFileType(tex[1]), tex[1]);
	image[2] = FreeImage_Load(FreeImage_GetFileType(tex[2]), tex[2]);
	image[3] = FreeImage_Load(FreeImage_GetFileType(tex[3]), tex[3]);
	image[4] = FreeImage_Load(FreeImage_GetFileType(tex[4]), tex[4]);
	image[5] = FreeImage_Load(FreeImage_GetFileType(tex[5]), tex[5]);

	if (_pShaderResourceView) _pShaderResourceView->Release();
	if (_pSamplerState) _pSamplerState->Release();

	D3D11_TEXTURE2D_DESC descTexture;
	descTexture.Width = FreeImage_GetWidth(image[0]);
	descTexture.Height = FreeImage_GetHeight(image[0]);
	descTexture.MipLevels = 1;
	descTexture.ArraySize = 6;
	descTexture.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
	descTexture.SampleDesc.Count = 1;
	descTexture.SampleDesc.Quality = 0;
	descTexture.Usage = D3D11_USAGE_IMMUTABLE;
	descTexture.BindFlags = D3D11_BIND_SHADER_RESOURCE;
	descTexture.CPUAccessFlags = 0;
	descTexture.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE;

	D3D11_SUBRESOURCE_DATA data[6];
	for (i = 0; i < 6; i++)
	{
		if (image[i] == NULL)
		{
			std::string text = "Error while loading image: ";
			text.append(tex[i]);
			MessageBoxA(NULL, text.c_str(), __FILE__, MB_OK);
			exit(1);
		}

		tmp = image[i];
		image[i] = FreeImage_ConvertTo32Bits(image[i]);
		FreeImage_Unload(tmp);

		data[i].pSysMem = FreeImage_GetBits(image[i]);
		data[i].SysMemPitch = 4 * descTexture.Width;
		data[i].SysMemSlicePitch = 0;
	}
	Device->CreateTexture2D(&descTexture, data, &texture);

	D3D11_SHADER_RESOURCE_VIEW_DESC descShaderResourceView;
	descShaderResourceView.Format = descTexture.Format;
	descShaderResourceView.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
	descShaderResourceView.TextureCube.MostDetailedMip = 0;
	descShaderResourceView.TextureCube.MipLevels = descTexture.MipLevels;
	Device->CreateShaderResourceView(texture, &descShaderResourceView, &_pShaderResourceView);

	D3D11_SAMPLER_DESC descSampler;
	descSampler.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
	descSampler.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
	descSampler.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
	descSampler.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
	descSampler.ComparisonFunc = D3D11_COMPARISON_NEVER;
	descSampler.MipLODBias = 0.0f;
	descSampler.MaxAnisotropy = 1;
	descSampler.BorderColor[0] = 0.0f;
	descSampler.BorderColor[1] = 0.0f;
	descSampler.BorderColor[2] = 0.0f;
	descSampler.BorderColor[3] = 0.0f;
	descSampler.MinLOD = 0;
	descSampler.MaxLOD = D3D11_FLOAT32_MAX;
	Device->CreateSamplerState(&descSampler, &_pSamplerState);

	texture->Release();
}
Пример #4
0
    //---------------------------------------------------------------------
    Codec::DecodeResult FreeImageCodec::decode(DataStreamPtr& input) const
    {
		// Set error handler
		FreeImage_SetOutputMessage(FreeImageLoadErrorHandler);

		// Buffer stream into memory (TODO: override IO functions instead?)
		MemoryDataStream memStream(input, true);

		FIMEMORY* fiMem = 
			FreeImage_OpenMemory(memStream.getPtr(), static_cast<DWORD>(memStream.size()));

		FIBITMAP* fiBitmap = FreeImage_LoadFromMemory(
			(FREE_IMAGE_FORMAT)mFreeImageType, fiMem);
		if (!fiBitmap)
		{
			OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, 
				"Error decoding image", 
				"FreeImageCodec::decode");
		}


		ImageData* imgData = OGRE_NEW ImageData();
		MemoryDataStreamPtr output;

		imgData->depth = 1; // only 2D formats handled by this codec
		imgData->width = FreeImage_GetWidth(fiBitmap);
		imgData->height = FreeImage_GetHeight(fiBitmap);
        imgData->num_mipmaps = 0; // no mipmaps in non-DDS 
        imgData->flags = 0;

		// Must derive format first, this may perform conversions
		
		FREE_IMAGE_TYPE imageType = FreeImage_GetImageType(fiBitmap);
		FREE_IMAGE_COLOR_TYPE colourType = FreeImage_GetColorType(fiBitmap);
		unsigned bpp = FreeImage_GetBPP(fiBitmap);

		switch(imageType)
		{
		case FIT_UNKNOWN:
		case FIT_COMPLEX:
		case FIT_UINT32:
		case FIT_INT32:
		case FIT_DOUBLE:
        default:
			OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, 
				"Unknown or unsupported image format", 
				"FreeImageCodec::decode");
				
			break;
		case FIT_BITMAP:
			// Standard image type
			// Perform any colour conversions for greyscale
			if (colourType == FIC_MINISWHITE || colourType == FIC_MINISBLACK)
			{
				FIBITMAP* newBitmap = FreeImage_ConvertToGreyscale(fiBitmap);
				// free old bitmap and replace
				FreeImage_Unload(fiBitmap);
				fiBitmap = newBitmap;
				// get new formats
				bpp = FreeImage_GetBPP(fiBitmap);
				colourType = FreeImage_GetColorType(fiBitmap);
			}
			// Perform any colour conversions for RGB
			else if (bpp < 8 || colourType == FIC_PALETTE || colourType == FIC_CMYK)
			{
				FIBITMAP* newBitmap = FreeImage_ConvertTo24Bits(fiBitmap);
				// free old bitmap and replace
				FreeImage_Unload(fiBitmap);
				fiBitmap = newBitmap;
				// get new formats
				bpp = FreeImage_GetBPP(fiBitmap);
				colourType = FreeImage_GetColorType(fiBitmap);
			}

			// by this stage, 8-bit is greyscale, 16/24/32 bit are RGB[A]
			switch(bpp)
			{
			case 8:
				imgData->format = PF_L8;
				break;
			case 16:
				// Determine 555 or 565 from green mask
				// cannot be 16-bit greyscale since that's FIT_UINT16
				if(FreeImage_GetGreenMask(fiBitmap) == FI16_565_GREEN_MASK)
				{
					imgData->format = PF_R5G6B5;
				}
				else
				{
					// FreeImage doesn't support 4444 format so must be 1555
					imgData->format = PF_A1R5G5B5;
				}
				break;
			case 24:
				// FreeImage differs per platform
				//     PF_BYTE_BGR[A] for little endian (== PF_ARGB native)
				//     PF_BYTE_RGB[A] for big endian (== PF_RGBA native)
#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_RGB
				imgData->format = PF_BYTE_RGB;
#else
				imgData->format = PF_BYTE_BGR;
#endif
				break;
			case 32:
#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_RGB
				imgData->format = PF_BYTE_RGBA;
#else
				imgData->format = PF_BYTE_BGRA;
#endif
				break;
				
				
			};
			break;
		case FIT_UINT16:
		case FIT_INT16:
			// 16-bit greyscale
			imgData->format = PF_L16;
			break;
		case FIT_FLOAT:
			// Single-component floating point data
			imgData->format = PF_FLOAT32_R;
			break;
		case FIT_RGB16:
			imgData->format = PF_SHORT_RGB;
			break;
		case FIT_RGBA16:
			imgData->format = PF_SHORT_RGBA;
			break;
		case FIT_RGBF:
			imgData->format = PF_FLOAT32_RGB;
			break;
		case FIT_RGBAF:
			imgData->format = PF_FLOAT32_RGBA;
			break;
			
			
		};

		unsigned char* srcData = FreeImage_GetBits(fiBitmap);
		unsigned srcPitch = FreeImage_GetPitch(fiBitmap);

		// Final data - invert image and trim pitch at the same time
		size_t dstPitch = imgData->width * PixelUtil::getNumElemBytes(imgData->format);
		imgData->size = dstPitch * imgData->height;
        // Bind output buffer
        output.bind(OGRE_NEW MemoryDataStream(imgData->size));

		uchar* pSrc;
		uchar* pDst = output->getPtr();
		for (size_t y = 0; y < imgData->height; ++y)
		{
			pSrc = srcData + (imgData->height - y - 1) * srcPitch;
			memcpy(pDst, pSrc, dstPitch);
			pDst += dstPitch;
		}

		
		FreeImage_Unload(fiBitmap);
		FreeImage_CloseMemory(fiMem);


        DecodeResult ret;
        ret.first = output;
        ret.second = CodecDataPtr(imgData);
		return ret;

    }
Пример #5
0
		Int32 loadTexture(Texture *out_texture, const char *fileAddress)
		{
			__BLITZ_ASSERT(out_texture);
			__BLITZ_ASSERT(fileAddress);
			auto existingTexture = textureList.find(std::string(fileAddress));
			if (existingTexture != textureList.end())
			{
				*out_texture = existingTexture->second;
				return 0;
			}
			FREE_IMAGE_FORMAT freeImageFormat;
			freeImageFormat = FreeImage_GetFileType(fileAddress, 0);
			if (freeImageFormat == FIF_UNKNOWN)
			{
				freeImageFormat = FreeImage_GetFIFFromFilename(fileAddress);
			}
			if (freeImageFormat == FIF_UNKNOWN)
			{
				__BLITZ_THROW_ERROR("Failed to load image \"" +
					std::string(fileAddress) + "\" : Image format is not supported.");
				return 1;
			}
			Bool loadAlphaChannel = 0;
			switch (freeImageFormat)
			{
			case FIF_BMP:
			case FIF_GIF:
			case FIF_JPEG:
				loadAlphaChannel = 0;
				break;
			case FIF_DDS:
			case FIF_PNG:
			case FIF_TARGA:
				loadAlphaChannel = 1;
				break;
			}
			if (FreeImage_FIFSupportsReading(freeImageFormat) == 0)
			{
				__BLITZ_THROW_ERROR("Failed to load image \"" +
					std::string(fileAddress) +
					"\" : Reading from this image format is not supported.");
				return 1;
			}
			FIBITMAP *freeImageBitmap = FreeImage_Load(freeImageFormat, fileAddress, 0);
			if (freeImageBitmap == 0)
			{
				__BLITZ_THROW_ERROR("Failed to load image \"" +
					std::string(fileAddress) + "\" : Failed to load image file.");
				return 1;
			}
			BYTE *imageData = FreeImage_GetBits(freeImageBitmap);
			if (imageData == 0)
			{
				__BLITZ_THROW_ERROR("Failed to load image \"" +
					std::string(fileAddress) + "\" : Failed to get image data.");
				return 1;
			}
			Int32 imageWidth = FreeImage_GetWidth(freeImageBitmap),
				imageHeight = FreeImage_GetHeight(freeImageBitmap);
			if (imageWidth <= 0 || imageHeight <= 0)
			{
				__BLITZ_THROW_ERROR("Failed to load image \"" +
					std::string(fileAddress) + "\" : Image dimensions are invalid.");
				return 1;
			}
			glGenTextures(1, out_texture);
			glBindTexture(GL_TEXTURE_2D, *out_texture);
			GLint imageFormat = loadAlphaChannel ? GL_BGRA : GL_BGR;
			glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, imageWidth, imageHeight, 0,
				imageFormat, GL_UNSIGNED_BYTE, imageData);
			glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
			glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
			glBindTexture(GL_TEXTURE_2D, 0);
			FreeImage_Unload(freeImageBitmap);
			std::pair<std::string, Texture> newPair =
				std::pair<std::string, Texture>(fileAddress, *out_texture);
			textureList.insert(newPair);
			blitz::__debug::throwMessage("Image \"" + std::string(fileAddress) +
				"\" loaded.");
			return 0;
		}
Пример #6
0
Texture* FreeImageImageCodec::load(const RawDataContainer& data, Texture* result)
{
    int len = (int)data.getSize();
    FIMEMORY *mem = 0;
    FIBITMAP *img = 0;
    Texture *retval = 0;

    try
    {
        mem = FreeImage_OpenMemory(static_cast<BYTE*>(const_cast<std::uint8_t*>(data.getDataPtr())), len);
        if (mem == 0)
            throw MemoryException("Unable to open memory stream, FreeImage_OpenMemory failed");

        FREE_IMAGE_FORMAT fif = FreeImage_GetFileTypeFromMemory(mem, len);

        if (fif == FIF_UNKNOWN) // it may be that it's TARGA or MNG
        {
            fif = FIF_TARGA;
            img = FreeImage_LoadFromMemory(fif, mem, 0);

            if (img == 0)
            {
                fif = FIF_MNG;
                img = FreeImage_LoadFromMemory(fif, mem, 0);
            }
        }
        else
            img = FreeImage_LoadFromMemory(fif, mem, 0);

        if (img == 0)
            throw GenericException("Unable to load image, FreeImage_LoadFromMemory failed");

        FIBITMAP *newImg = FreeImage_ConvertTo32Bits(img);
        if (newImg == 0)
            throw GenericException("Unable to convert image, FreeImage_ConvertTo32Bits failed");
        FreeImage_Unload(img);
        img = newImg;
        newImg = 0;

        // FreeImage pixel format for little-endian architecture (which CEGUI
        // supports) is like BGRA. We need to convert that to RGBA.
        //
        // It is now:
        // RED_MASK		0x00FF0000
        // GREEN_MASK	0x0000FF00
        // BLUE_MASK	0x000000FF
        // ALPHA_MASK	0xFF000000
        //
        // It should be:
        // RED_MASK		0x000000FF
        // GREEN_MASK	0x0000FF00
        // BLUE_MASK	0x00FF0000
        // ALPHA_MASK	0xFF000000

        unsigned int pitch = FreeImage_GetPitch(img);
        unsigned int height = FreeImage_GetHeight(img);
        unsigned int width = FreeImage_GetWidth(img);
        std::uint8_t *rawBuf = new std::uint8_t[width * height << 2];

        // convert the bitmap to raw bits (top-left pixel first)
        FreeImage_ConvertToRawBits(rawBuf, img, pitch, 32,
                                   FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK, true);

        // We need to convert pixel format a little
        // NB: little endian only - I think(!)
#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_BGR
        for (unsigned int i = 0; i < height; ++i)
        {
            for (unsigned int j = 0; j < width; ++j)
            {
                unsigned int p = *(((unsigned int*)(rawBuf + i * pitch)) + j);
                unsigned int r = (p >> 16) & 0x000000FF;
                unsigned int b = (p << 16) & 0x00FF0000;
                p &= 0xFF00FF00;
                p |= r | b;
                // write the adjusted pixel back
                *(((unsigned int*)(rawBuf + i * pitch)) + j) = p;
            }
        }
#endif
        FreeImage_Unload(img);
        img = 0;

        result->loadFromMemory(rawBuf, Sizef(width, height), Texture::PF_RGBA);
        delete [] rawBuf;
        retval = result;
    }
    catch (Exception&)
    {
    }

    if (img != 0) FreeImage_Unload(img);
    if (mem != 0) FreeImage_CloseMemory(mem);

    return retval;
}
Пример #7
0
static void *bg_new_img(void *data)
{
  /* so we can poll for it */
  block_usr1_signal();

  struct imv_loader *ldr = data;
  char path[PATH_MAX] = "-";

  pthread_mutex_lock(&ldr->lock);
  int from_stdin = !strncmp(path, ldr->path, 2);
  if(!from_stdin) {
    (void)snprintf(path, PATH_MAX, "%s", ldr->path);
  }
  pthread_mutex_unlock(&ldr->lock);

  FREE_IMAGE_FORMAT fmt;
  if (from_stdin) {
    pthread_mutex_lock(&ldr->lock);
    ldr->fi_buffer = FreeImage_OpenMemory(ldr->buffer, ldr->buffer_size);
    fmt = FreeImage_GetFileTypeFromMemory(ldr->fi_buffer, 0);
    pthread_mutex_unlock(&ldr->lock);
  } else {
    fmt = FreeImage_GetFileType(path, 0);
  }
  if(fmt == FIF_UNKNOWN) {
    if (from_stdin) {
      pthread_mutex_lock(&ldr->lock);
      FreeImage_CloseMemory(ldr->fi_buffer);
      pthread_mutex_unlock(&ldr->lock);
    }
    error_occurred(ldr);
    return NULL;
  }

  int num_frames = 1;
  FIMULTIBITMAP *mbmp = NULL;
  FIBITMAP *bmp = NULL;
  int width, height;
  int raw_frame_time = 100; /* default to 100 */

  if(fmt == FIF_GIF) {
    if(from_stdin) {
      pthread_mutex_lock(&ldr->lock);
      mbmp = FreeImage_LoadMultiBitmapFromMemory(FIF_GIF, ldr->fi_buffer,
          GIF_LOAD256);
      pthread_mutex_unlock(&ldr->lock);
    } else {
      mbmp = FreeImage_OpenMultiBitmap(FIF_GIF, path,
      /* don't create file */ 0,
      /* read only */ 1,
      /* keep in memory */ 1,
      /* flags */ GIF_LOAD256);
    }
    if(!mbmp) {
      error_occurred(ldr);
      return NULL;
    }

    num_frames = FreeImage_GetPageCount(mbmp);

    FIBITMAP *frame = FreeImage_LockPage(mbmp, 0);
    width = FreeImage_GetWidth(frame);
    height = FreeImage_GetHeight(frame);
    bmp = FreeImage_ConvertTo32Bits(frame);

    /* get duration of first frame */
    FITAG *tag = NULL;
    FreeImage_GetMetadata(FIMD_ANIMATION, frame, "FrameTime", &tag);
    if(FreeImage_GetTagValue(tag)) {
      raw_frame_time = *(int*)FreeImage_GetTagValue(tag);
    }
    FreeImage_UnlockPage(mbmp, frame, 0);

  } else {
    /* Future TODO: If we load image line-by-line we could stop loading large
     * ones before wasting much more time/memory on them. */

    int flags = (fmt == FIF_JPEG) ? JPEG_EXIFROTATE : 0;
    FIBITMAP *image;
    if(from_stdin) {
      pthread_mutex_lock(&ldr->lock);
      image = FreeImage_LoadFromMemory(fmt, ldr->fi_buffer, flags);
      pthread_mutex_unlock(&ldr->lock);
    } else {
      image = FreeImage_Load(fmt, path, flags);
    }
    if(!image) {
      error_occurred(ldr);
      pthread_mutex_lock(&ldr->lock);
      FreeImage_CloseMemory(ldr->fi_buffer);
      ldr->fi_buffer = NULL;
      pthread_mutex_unlock(&ldr->lock);
      return NULL;
    }

    /* Check for cancellation before we convert pixel format */
    if(is_thread_cancelled()) {
      FreeImage_Unload(image);
      return NULL;
    }

    width = FreeImage_GetWidth(bmp);
    height = FreeImage_GetHeight(bmp);
    bmp = FreeImage_ConvertTo32Bits(image);
    FreeImage_Unload(image);
  }

  /* now update the loader */
  pthread_mutex_lock(&ldr->lock);

  /* check for cancellation before finishing */
  if(is_thread_cancelled()) {
    if(mbmp) {
      FreeImage_CloseMultiBitmap(mbmp, 0);
    }
    if(bmp) {
      FreeImage_Unload(bmp);
    }
    pthread_mutex_unlock(&ldr->lock);
    return NULL;
  }

  if(ldr->mbmp) {
    FreeImage_CloseMultiBitmap(ldr->mbmp, 0);
  }

  if(ldr->bmp) {
    FreeImage_Unload(ldr->bmp);
  }

  ldr->mbmp = mbmp;
  ldr->bmp = bmp;
  if(ldr->out_bmp) {
    FreeImage_Unload(ldr->out_bmp);
  }
  ldr->out_bmp = FreeImage_Clone(bmp);
  ldr->out_is_new_image = 1;
  ldr->width = width;
  ldr->height = height;
  ldr->cur_frame = 0;
  ldr->next_frame = 1;
  ldr->num_frames = num_frames;
  ldr->frame_time = (double)raw_frame_time * 0.0001;

  pthread_mutex_unlock(&ldr->lock);
  return NULL;
}
Пример #8
0
bool Texture::loadTexture(const char* path, bool generateMipMaps, bool defaultParameters)
{
	printf("Reading image %s\n", path);

	FREE_IMAGE_FORMAT format = FIF_UNKNOWN;
	FIBITMAP* dib(0);

	format = FreeImage_GetFileType(path, 0); // Check the file signature and deduce its format

	if (format == FIF_UNKNOWN) // If still unknown, try to guess the file format from the file extension
		format = FreeImage_GetFIFFromFilename(path);

	if (format == FIF_UNKNOWN) // If still unkown, return failure
	{
		printf("Failure(1)\n");
		return false;
	}

	// Check if the plugin has reading capabilities and load the file
	if (FreeImage_FIFSupportsReading(format))
		dib = FreeImage_Load(format, path);
	if (!dib)
	{
		printf("Failure(2)\n");
		return false;
	}

	BYTE* dataPointer = FreeImage_GetBits(dib);	// Retrieve image data

	int width = FreeImage_GetWidth(dib); // Get the image width and height
	int height = FreeImage_GetHeight(dib);
	int BPP = FreeImage_GetBPP(dib); // bytes per pixel

	// If somehow one of these failed (they shouldn't), return failure
	if (dataPointer == NULL || width == 0 || height == 0)
	{
		printf("Failure(3)\n");
		return false;
	}

	glGenTextures(1, &textureID);
	glBindTexture(GL_TEXTURE_2D, textureID);

	int texFormat = BPP == 24 ? GL_BGR : BPP == 8 ? GL_LUMINANCE : 0;
	//int internalFormat = BPP == 24 ? GL_RGB : GL_DEPTH_COMPONENT;

	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, texFormat, GL_UNSIGNED_BYTE, dataPointer);

	FreeImage_Unload(dib);

	if (defaultParameters)
	{
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
	}
	if (generateMipMaps)
	{
		glGenerateMipmap(GL_TEXTURE_2D);
		mipMapsGenerated = generateMipMaps;
	}

	return true;
}
Пример #9
0
        Texture* TextureManager::addTexture( const std::string& filename )
        {
            Texture* ret = nullptr;

            FREE_IMAGE_FORMAT fif = FIF_UNKNOWN;
            FIBITMAP* dib = nullptr; // TODO This name is nonsense, change it

            // Find format from file signature
            fif = FreeImage_GetFileType( filename.c_str(), 0 );

            if ( FIF_UNKNOWN == fif )
            {
                // Find format from file extension
                fif = FreeImage_GetFIFFromFilename( filename.c_str() );
            }

            if ( FIF_UNKNOWN == fif )
            {
                // Still unknown
                std::string error = "Cannot determine " + filename + " image format.";
                LOG( logERROR ) << error;
                CORE_ASSERT( 0, error.c_str() );

                return nullptr;
            }

            if ( FreeImage_FIFSupportsReading( fif ) )
            {
                dib = FreeImage_Load( fif, filename.c_str() );
            }

            std::string error = "Something went wrong while trying to load " + filename + ".";
            //CORE_ASSERT(dib, error.c_str());

            if ( nullptr == dib )
            {
                LOG( logERROR ) << error;
                return nullptr;
            }

            ret = new Texture( filename, GL_TEXTURE_2D );
            unsigned char* data = FreeImage_GetBits( dib );

            int bpp = FreeImage_GetBPP( dib );
            int format = ( bpp == 24 ? GL_BGR : 0 ); // TODO Handle other formats
            int internal = ( bpp == 24 ? GL_RGB : 0 ); // TODO Handle other formats
            int w = FreeImage_GetWidth( dib );
            int h = FreeImage_GetHeight( dib );

            // FIXME(Charly): Use VLOG instead of the check
            if ( m_verbose )
            {
                LOG( logINFO ) << "Image stats (" << filename << ") :\n"
                               << "\tBPP    : 0x" << std::hex << bpp << std::dec << std::endl
                               << "\tFormat : 0x" << std::hex << format << std::dec << std::endl
                               << "\tSize   : " << w << ", " << h;
            }


            CORE_ASSERT( data, "Data is null" );

            ret->initGL( internal, w, h, format, GL_UNSIGNED_BYTE, data );
            ret->genMipmap( GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR );

            m_textures.insert( TexturePair( filename, ret ) );

            FreeImage_Unload( dib );

            return ret;
        }
Пример #10
0
unsigned DLL_CALLCONV
FreeImage_GetDIBSize(FIBITMAP *dib) {
	return (dib) ? sizeof(BITMAPINFOHEADER) + (FreeImage_GetColorsUsed(dib) * sizeof(RGBQUAD)) + (FreeImage_GetPitch(dib) * FreeImage_GetHeight(dib)) : 0;
}
Пример #11
0
FIBITMAP * DLL_CALLCONV
FreeImage_ConvertToUINT16(FIBITMAP *dib) {
	FIBITMAP *src = NULL;
	FIBITMAP *dst = NULL;

	if(!FreeImage_HasPixels(dib)) return NULL;

	const FREE_IMAGE_TYPE src_type = FreeImage_GetImageType(dib);

	// check for allowed conversions 
	switch(src_type) {
		case FIT_BITMAP:
		{
			// convert to greyscale if needed
			if((FreeImage_GetBPP(dib) == 8) && (FreeImage_GetColorType(dib) == FIC_MINISBLACK)) {
				src = dib;
			} else {
				src = FreeImage_ConvertToGreyscale(dib);
				if(!src) return NULL;
			}
			break;
		}
		case FIT_UINT16:
			// UINT16 type : clone the src
			return FreeImage_Clone(dib);
			break;
		case FIT_RGB16:
			// allow conversion from 48-bit RGB
			src = dib;
			break;
		case FIT_RGBA16:
			// allow conversion from 64-bit RGBA (ignore the alpha channel)
			src = dib;
			break;
		default:
			return NULL;
	}

	// allocate dst image

	const unsigned width = FreeImage_GetWidth(src);
	const unsigned height = FreeImage_GetHeight(src);

	dst = FreeImage_AllocateT(FIT_UINT16, width, height);
	if(!dst) return NULL;

	// copy metadata from src to dst
	FreeImage_CloneMetadata(dst, src);

	// convert from src type to UINT16

	switch(src_type) {
		case FIT_BITMAP:
		{
			for(unsigned y = 0; y < height; y++) {
				const BYTE *src_bits = (BYTE*)FreeImage_GetScanLine(src, y);
				WORD *dst_bits = (WORD*)FreeImage_GetScanLine(dst, y);
				for(unsigned x = 0; x < width; x++) {
					dst_bits[x] = src_bits[x] << 8;
				}
			}
		}
		break;

		case FIT_RGB16:
		{
			for(unsigned y = 0; y < height; y++) {
				const FIRGB16 *src_bits = (FIRGB16*)FreeImage_GetScanLine(src, y);
				WORD *dst_bits = (WORD*)FreeImage_GetScanLine(dst, y);
				for(unsigned x = 0; x < width; x++) {
					// convert to grey
					dst_bits[x] = (WORD)LUMA_REC709(src_bits[x].red, src_bits[x].green, src_bits[x].blue);
				}
			}
		}
		break;

		case FIT_RGBA16:
		{
			for(unsigned y = 0; y < height; y++) {
				const FIRGBA16 *src_bits = (FIRGBA16*)FreeImage_GetScanLine(src, y);
				WORD *dst_bits = (WORD*)FreeImage_GetScanLine(dst, y);
				for(unsigned x = 0; x < width; x++) {
					// convert to grey
					dst_bits[x] = (WORD)LUMA_REC709(src_bits[x].red, src_bits[x].green, src_bits[x].blue);
				}
			}
		}
		break;

		default:
			break;
	}

	if(src != dib) {
		FreeImage_Unload(src);
	}

	return dst;
}
Пример #12
0
FREE_IMAGE_COLOR_TYPE DLL_CALLCONV
FreeImage_GetColorType(FIBITMAP *dib) {
	RGBQUAD *rgb;

	const FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(dib);

	// special bitmap type
	if(image_type != FIT_BITMAP) {
		switch(image_type) {
			case FIT_RGB16:
			case FIT_RGBF:
				return FIC_RGB;
			case FIT_RGBA16:
			case FIT_RGBAF:
				return FIC_RGBALPHA;
		}

		return FIC_MINISBLACK;
	}

	// standard image type
	switch (FreeImage_GetBPP(dib)) {
		case 1:
		{
			rgb = FreeImage_GetPalette(dib);

			if ((rgb->rgbRed == 0) && (rgb->rgbGreen == 0) && (rgb->rgbBlue == 0)) {
				rgb++;

				if ((rgb->rgbRed == 255) && (rgb->rgbGreen == 255) && (rgb->rgbBlue == 255))
					return FIC_MINISBLACK;				
			}

			if ((rgb->rgbRed == 255) && (rgb->rgbGreen == 255) && (rgb->rgbBlue == 255)) {
				rgb++;

				if ((rgb->rgbRed == 0) && (rgb->rgbGreen == 0) && (rgb->rgbBlue == 0))
					return FIC_MINISWHITE;				
			}

			return FIC_PALETTE;
		}

		case 4:
		case 8:	// Check if the DIB has a color or a greyscale palette
		{
			int ncolors = FreeImage_GetColorsUsed(dib);
		    int minisblack = 1;
			rgb = FreeImage_GetPalette(dib);

			for (int i = 0; i < ncolors; i++) {
				if ((rgb->rgbRed != rgb->rgbGreen) || (rgb->rgbRed != rgb->rgbBlue))
					return FIC_PALETTE;

				// The DIB has a color palette if the greyscale isn't a linear ramp
				// Take care of reversed grey images
				if (rgb->rgbRed != i) {
					if ((ncolors-i-1) != rgb->rgbRed)
						return FIC_PALETTE;
				    else
						minisblack = 0;
				}

				rgb++;
			}

			return minisblack ? FIC_MINISBLACK : FIC_MINISWHITE;
		}

		case 16:
		case 24:
			return FIC_RGB;

		case 32:
		{
			if (FreeImage_GetICCProfile(dib)->flags & FIICC_COLOR_IS_CMYK)
				return FIC_CMYK;

			for (unsigned y = 0; y < FreeImage_GetHeight(dib); y++) {
				rgb = (RGBQUAD *)FreeImage_GetScanLine(dib, y);

				for (unsigned x = 0; x < FreeImage_GetWidth(dib); x++)
					if (rgb[x].rgbReserved != 0xFF)
						return FIC_RGBALPHA;			
			}

			return FIC_RGB;
		}
				
		default :
			return FIC_MINISBLACK;
	}
}
Пример #13
0
FIBITMAP * DLL_CALLCONV
FreeImage_Clone(FIBITMAP *dib) {
	if(!dib) return NULL;

	unsigned width  = FreeImage_GetWidth(dib);
	unsigned height = FreeImage_GetHeight(dib);
	unsigned bpp    = FreeImage_GetBPP(dib);
	
	// check for pixel availability ...
	BOOL header_only = FreeImage_HasPixels(dib) ? FALSE : TRUE;

	// allocate a new dib
	FIBITMAP *new_dib = FreeImage_AllocateHeaderT(header_only, FreeImage_GetImageType(dib), width, height, bpp, 
			FreeImage_GetRedMask(dib), FreeImage_GetGreenMask(dib), FreeImage_GetBlueMask(dib));

	if (new_dib) {
		// save ICC profile links
		FIICCPROFILE *src_iccProfile = FreeImage_GetICCProfile(dib);
		FIICCPROFILE *dst_iccProfile = FreeImage_GetICCProfile(new_dib);

		// save metadata links
		METADATAMAP *src_metadata = ((FREEIMAGEHEADER *)dib->data)->metadata;
		METADATAMAP *dst_metadata = ((FREEIMAGEHEADER *)new_dib->data)->metadata;

		// calculate the size of a FreeImage image
		// align the palette and the pixels on a FIBITMAP_ALIGNMENT bytes alignment boundary
		// palette is aligned on a 16 bytes boundary
		// pixels are aligned on a 16 bytes boundary

		size_t dib_size = FreeImage_GetImageSizeHeader(header_only, width, height, bpp); 

		// copy the bitmap + internal pointers (remember to restore new_dib internal pointers later)
		memcpy(new_dib->data, dib->data, dib_size);

		// reset ICC profile link for new_dib
		memset(dst_iccProfile, 0, sizeof(FIICCPROFILE));

		// restore metadata link for new_dib
		((FREEIMAGEHEADER *)new_dib->data)->metadata = dst_metadata;

		// reset thumbnail link for new_dib
		((FREEIMAGEHEADER *)new_dib->data)->thumbnail = NULL;

		// copy possible ICC profile
		FreeImage_CreateICCProfile(new_dib, src_iccProfile->data, src_iccProfile->size);
		dst_iccProfile->flags = src_iccProfile->flags;

		// copy metadata models
		for(METADATAMAP::iterator i = (*src_metadata).begin(); i != (*src_metadata).end(); i++) {
			int model = (*i).first;
			TAGMAP *src_tagmap = (*i).second;

			if(src_tagmap) {
				// create a metadata model
				TAGMAP *dst_tagmap = new(std::nothrow) TAGMAP();

				if(dst_tagmap) {
					// fill the model
					for(TAGMAP::iterator j = src_tagmap->begin(); j != src_tagmap->end(); j++) {
						std::string dst_key = (*j).first;
						FITAG *dst_tag = FreeImage_CloneTag( (*j).second );

						// assign key and tag value
						(*dst_tagmap)[dst_key] = dst_tag;
					}

					// assign model and tagmap
					(*dst_metadata)[model] = dst_tagmap;
				}
			}
		}

		// copy the thumbnail
		FreeImage_SetThumbnail(new_dib, FreeImage_GetThumbnail(dib));

		return new_dib;
	}

	return NULL;
}
Пример #14
0
int
main(int argc, char *argv[])
{
    printf("%s Starting...\n\n", argv[0]);

    try
    {
        std::string sFilename;
        char *filePath = sdkFindFilePath("Lena.pgm", argv[0]);

        if (filePath)
        {
            sFilename = filePath;
        }
        else
        {
            printf("Error unable to find Lena.pgm\n");
            exit(EXIT_FAILURE);
        }

        // set your own FreeImage error handler
        FreeImage_SetOutputMessage(FreeImageErrorHandler);

        cudaDeviceInit(argc, (const char **)argv);

		// Min spec is SM 1.0 devices
		if (printfNPPinfo(argc, argv, 1, 0) == false) 
		{
	        cudaDeviceReset();
			exit(EXIT_SUCCESS);
		}

        if (argc > 1)
        {
            sFilename = argv[1];
        }

        // if we specify the filename at the command line, then we only test sFilename
        // otherwise we will check both sFilename[0,1]
        int file_errors = 0;
        std::ifstream infile(sFilename.data(), std::ifstream::in);

        if (infile.good())
        {
            std::cout << "freeImageInteropNPP opened: <" << sFilename.data() << "> successfully!" << std::endl;
            file_errors = 0;
            infile.close();
        }
        else
        {
            std::cout << "freeImageInteropNPP unable to open: <" << sFilename.data() << ">" << std::endl;
            file_errors++;
            infile.close();
        }

        if (file_errors > 0)
        {
            exit(EXIT_FAILURE);
        }

        std::string sResultFilename = sFilename;

        std::string::size_type dot = sResultFilename.rfind('.');

        if (dot != std::string::npos)
        {
            sResultFilename = sResultFilename.substr(0, dot);
        }

        sResultFilename += "_boxFilterFII.pgm";

        if (argc >= 3)
        {
            sResultFilename = argv[2];
        }

        FREE_IMAGE_FORMAT eFormat = FreeImage_GetFileType(sFilename.c_str());

        // no signature? try to guess the file format from the file extension
        if (eFormat == FIF_UNKNOWN)
        {
            eFormat = FreeImage_GetFIFFromFilename(sFilename.c_str());
        }

        NPP_ASSERT(eFormat != FIF_UNKNOWN);
        // check that the plugin has reading capabilities ...
        FIBITMAP *pBitmap;

        if (FreeImage_FIFSupportsReading(eFormat))
        {
            pBitmap = FreeImage_Load(eFormat, sFilename.c_str());
        }

        NPP_ASSERT(pBitmap != 0);
        // Dump the bitmap information to the console
        std::cout << (*pBitmap) << std::endl;
        // make sure this is an 8-bit single channel image
        NPP_ASSERT(FreeImage_GetColorType(pBitmap) == FIC_MINISBLACK);
        NPP_ASSERT(FreeImage_GetBPP(pBitmap) == 8);

        unsigned int nImageWidth  = FreeImage_GetWidth(pBitmap);
        unsigned int nImageHeight = FreeImage_GetHeight(pBitmap);
        unsigned int nSrcPitch    = FreeImage_GetPitch(pBitmap);
        unsigned char *pSrcData  = FreeImage_GetBits(pBitmap);

        int nSrcPitchCUDA;
        Npp8u *pSrcImageCUDA = nppiMalloc_8u_C1(nImageWidth, nImageHeight, &nSrcPitchCUDA);
        NPP_ASSERT_NOT_NULL(pSrcImageCUDA);
        // copy image loaded via FreeImage to into CUDA device memory, i.e.
        // transfer the image-data up to the GPU's video-memory
        NPP_CHECK_CUDA(cudaMemcpy2D(pSrcImageCUDA, nSrcPitchCUDA, pSrcData, nSrcPitch,
                                    nImageWidth, nImageHeight, cudaMemcpyHostToDevice));

        // define size of the box filter
        const NppiSize  oMaskSize   = {7, 7};
        const NppiPoint oMaskAchnor = {0, 0};
        // compute maximal result image size
        const NppiSize  oSizeROI = {nImageWidth  - (oMaskSize.width - 1),
                                    nImageHeight - (oMaskSize.height - 1)
                                   };
        // allocate result image memory
        int nDstPitchCUDA;
        Npp8u *pDstImageCUDA = nppiMalloc_8u_C1(oSizeROI.width, oSizeROI.height, &nDstPitchCUDA);
        NPP_ASSERT_NOT_NULL(pDstImageCUDA);
        NPP_CHECK_NPP(nppiFilterBox_8u_C1R(pSrcImageCUDA, nSrcPitchCUDA, pDstImageCUDA, nDstPitchCUDA,
                                           oSizeROI, oMaskSize, oMaskAchnor));
        // create the result image storage using FreeImage so we can easily
        // save
        FIBITMAP *pResultBitmap = FreeImage_Allocate(oSizeROI.width, oSizeROI.height, 8 /* bits per pixel */);
        NPP_ASSERT_NOT_NULL(pResultBitmap);
        unsigned int nResultPitch   = FreeImage_GetPitch(pResultBitmap);
        unsigned char *pResultData = FreeImage_GetBits(pResultBitmap);

        NPP_CHECK_CUDA(cudaMemcpy2D(pResultData, nResultPitch, pDstImageCUDA, nDstPitchCUDA,
                                    oSizeROI.width, oSizeROI.height, cudaMemcpyDeviceToHost));
        // now save the result image
        bool bSuccess;
        bSuccess = FreeImage_Save(FIF_PGM, pResultBitmap, sResultFilename.c_str(), 0) == TRUE;
        NPP_ASSERT_MSG(bSuccess, "Failed to save result image.");

        //free nppiImage
        nppiFree(pSrcImageCUDA);
        nppiFree(pDstImageCUDA);

        cudaDeviceReset();
        exit(EXIT_SUCCESS);
    }
    catch (npp::Exception &rException)
    {
        std::cerr << "Program error! The following exception occurred: \n";
        std::cerr << rException << std::endl;
        std::cerr << "Aborting." << std::endl;
        exit(EXIT_FAILURE);
    }
    catch (...)
    {
        std::cerr << "Program error! An unknow type of exception occurred. \n";
        std::cerr << "Aborting." << std::endl;
        exit(EXIT_FAILURE);
    }

    exit(EXIT_SUCCESS);
}
Пример #15
0
unsigned fipImage::getHeight() const {
	return FreeImage_GetHeight(_dib); 
}
mng_ptr
mymnggetcanvasline(mng_handle mng, mng_uint32 line) {
	FIBITMAP *bitmap = ((mngstuff *)mng_get_userdata(mng))->bitmap;

	return FreeImage_GetScanLine(bitmap, FreeImage_GetHeight(bitmap) - line - 1);
}
Пример #17
0
BYTE* fipImage::getScanLine(unsigned scanline) const {
	if(scanline < FreeImage_GetHeight(_dib)) {
		return FreeImage_GetScanLine(_dib, scanline);
	}
	return NULL;
}
Пример #18
0
void load_image(const char *fname) {

    // active only for static linking
    #ifdef FREEIMAGE_LIB
        FreeImage_Initialise();
    #endif

    FIBITMAP *bitmap;
    // Get the format of the image file
    FREE_IMAGE_FORMAT fif =FreeImage_GetFileType(fname, 0);

    // If the format can't be determined, try to guess the format from the file name
    if(fif == FIF_UNKNOWN) {
        fif = FreeImage_GetFIFFromFilename(fname);
    }

    // Load the data in bitmap if possible
    if(fif != FIF_UNKNOWN && FreeImage_FIFSupportsReading(fif)) {
        bitmap = FreeImage_Load(fif, fname);
    }
    else {
        bitmap = NULL;
    }

    // PROCESS IMAGE if bitmap was successfully initialized
    if(bitmap) {
        unsigned int w = FreeImage_GetWidth(bitmap);
        unsigned int h = FreeImage_GetHeight(bitmap);
        unsigned pixel_size = FreeImage_GetBPP(bitmap);

        // Get a pointer to the pixel data
        BYTE *data = (BYTE*)FreeImage_GetBits(bitmap);

        // Process only RGB and RGBA images
        if(pixel_size == 24) {
            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_BGR, GL_UNSIGNED_BYTE, (GLvoid*)data);
        }
        else if (pixel_size == 32) {
            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_BGRA, GL_UNSIGNED_BYTE, (GLvoid*)data);
        }
        else {
            std::cerr << "pixel size = " << pixel_size << " don't know how to process this case. I'm out!" << std::endl;
            exit(-1);
        }
        
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    }
    else {
        std::cerr << "Unable to load the image file " << fname  << " I'm out!" << std::endl;
        exit(-1);
    }

    // Clean bitmap;
    FreeImage_Unload(bitmap);

    // active only for static linking
    #ifdef FREEIMAGE_LIB
        FreeImage_DeInitialise();
    #endif  
}
Пример #19
0
bool CPicture::Load(tstring sFilePathName)
{
	bool bResult = false;
	bIsIcon = false;
	lpIcons = NULL;
	//CFile PictureFile;
	//CFileException e;
	FreePictureData(); // Important - Avoid Leaks...

	// No-op if no file specified
	if (sFilePathName.empty())
		return true;

	// Load & initialize the GDI+ library if available
	HMODULE hGdiPlusLib = AtlLoadSystemLibraryUsingFullPath(_T("gdiplus.dll"));
	if (hGdiPlusLib && GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL) == Ok)
	{
		bHaveGDIPlus = true;
	}
	// Since we loaded the gdiplus.dll only to check if it's available, we
	// can safely free the library here again - GdiplusStartup() loaded it too
	// and reference counting will make sure that it stays loaded until GdiplusShutdown()
	// is called.
	FreeLibrary(hGdiPlusLib);

	// Attempt to load using GDI+ if available
	if (bHaveGDIPlus)
	{
		pBitmap = new Bitmap(sFilePathName.c_str(), FALSE);
		GUID guid;
		pBitmap->GetRawFormat(&guid);

		if (pBitmap->GetLastStatus() != Ok)
		{
			delete pBitmap;
			pBitmap = NULL;
		}

		// gdiplus only loads the first icon found in an icon file
		// so we have to handle icon files ourselves :(

		// Even though gdiplus can load icons, it can't load the new
		// icons from Vista - in Vista, the icon format changed slightly.
		// But the LoadIcon/LoadImage API still can load those icons,
		// at least those dimensions which are also used on pre-Vista
		// systems.
		// For that reason, we don't rely on gdiplus telling us if
		// the image format is "icon" or not, we also check the
		// file extension for ".ico".
		std::transform(sFilePathName.begin(), sFilePathName.end(), sFilePathName.begin(), ::tolower);
		bIsIcon = (guid == ImageFormatIcon) || (wcsstr(sFilePathName.c_str(), L".ico") != NULL) || (wcsstr(sFilePathName.c_str(), L".cur") != NULL);
		bIsTiff = (guid == ImageFormatTIFF) || (_tcsstr(sFilePathName.c_str(), _T(".tiff")) != NULL);
		m_Name = sFilePathName;

		if (bIsIcon)
		{
			// Icon file, get special treatment...
			if (pBitmap)
			{
				// Cleanup first...
				delete (pBitmap);
				pBitmap = NULL;
				bIsIcon = true;
			}

			CAutoFile hFile = CreateFile(sFilePathName.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
			if (hFile)
			{
				BY_HANDLE_FILE_INFORMATION fileinfo;
				if (GetFileInformationByHandle(hFile, &fileinfo))
				{
					lpIcons = new BYTE[fileinfo.nFileSizeLow];
					DWORD readbytes;
					if (ReadFile(hFile, lpIcons, fileinfo.nFileSizeLow, &readbytes, NULL))
					{
						// we have the icon. Now gather the information we need later
						if (readbytes >= sizeof(ICONDIR))
						{
							// we are going to open same file second time so we have to close the file now
							hFile.CloseHandle();

							LPICONDIR lpIconDir = (LPICONDIR)lpIcons;
							if ((lpIconDir->idCount) && ((lpIconDir->idCount * sizeof(ICONDIR)) <= fileinfo.nFileSizeLow))
							{
								try
								{
									bResult = false;
									nCurrentIcon = 0;
									hIcons = new HICON[lpIconDir->idCount];
									// check that the pointers point to data that we just loaded
									if (((BYTE*)lpIconDir->idEntries > (BYTE*)lpIconDir) && 
										(((BYTE*)lpIconDir->idEntries) + (lpIconDir->idCount * sizeof(ICONDIRENTRY)) < ((BYTE*)lpIconDir) + fileinfo.nFileSizeLow))
									{
										m_Width = lpIconDir->idEntries[0].bWidth;
										m_Height = lpIconDir->idEntries[0].bHeight;
										bResult = true;
										for (int i=0; i<lpIconDir->idCount; ++i)
										{
											hIcons[i] = (HICON)LoadImage(NULL, sFilePathName.c_str(), IMAGE_ICON,
																		 lpIconDir->idEntries[i].bWidth,
																		 lpIconDir->idEntries[i].bHeight,
																		 LR_LOADFROMFILE);
											if (hIcons[i] == NULL)
											{
												// if the icon couldn't be loaded, the data is most likely corrupt
												delete [] lpIcons;
												lpIcons = NULL;
												bResult = false;
												break;
											}
										}
									}
								}
								catch (...)
								{
									delete [] lpIcons;
									lpIcons = NULL;
									bResult = false;
								}
							}
							else
							{
								delete [] lpIcons;
								lpIcons = NULL;
								bResult = false;
							}
						}
						else
						{
							delete [] lpIcons;
							lpIcons = NULL;
							bResult = false;
						}
					}
					else
					{
						delete [] lpIcons;
						lpIcons = NULL;
					}
				}
			}
		}
		else if (pBitmap)	// Image loaded successfully with GDI+
		{
			m_Height = pBitmap->GetHeight();
			m_Width = pBitmap->GetWidth();
			bResult = true;
		}

		// If still failed to load the file...
		if (!bResult)
		{
			// Attempt to load the FreeImage library as an optional DLL to support additional formats

			// NOTE: Currently just loading via FreeImage & using GDI+ for drawing.
			// It might be nice to remove this dependency in the future.
			HMODULE hFreeImageLib = LoadLibrary(_T("FreeImage.dll"));

			// FreeImage DLL functions
			typedef const char* (__stdcall *FreeImage_GetVersion_t)(void);
			typedef int			(__stdcall *FreeImage_GetFileType_t)(const TCHAR *filename, int size);
			typedef int			(__stdcall *FreeImage_GetFIFFromFilename_t)(const TCHAR *filename);
			typedef void*		(__stdcall *FreeImage_Load_t)(int format, const TCHAR *filename, int flags);
			typedef void		(__stdcall *FreeImage_Unload_t)(void* dib);
			typedef int			(__stdcall *FreeImage_GetColorType_t)(void* dib);
			typedef unsigned	(__stdcall *FreeImage_GetWidth_t)(void* dib);
			typedef unsigned	(__stdcall *FreeImage_GetHeight_t)(void* dib);
			typedef void		(__stdcall *FreeImage_ConvertToRawBits_t)(BYTE *bits, void *dib, int pitch, unsigned bpp, unsigned red_mask, unsigned green_mask, unsigned blue_mask, BOOL topdown);

			//FreeImage_GetVersion_t FreeImage_GetVersion = NULL;
			FreeImage_GetFileType_t FreeImage_GetFileType = NULL;
			FreeImage_GetFIFFromFilename_t FreeImage_GetFIFFromFilename = NULL;
			FreeImage_Load_t FreeImage_Load = NULL;
			FreeImage_Unload_t FreeImage_Unload = NULL;
			//FreeImage_GetColorType_t FreeImage_GetColorType = NULL;
			FreeImage_GetWidth_t FreeImage_GetWidth = NULL;
			FreeImage_GetHeight_t FreeImage_GetHeight = NULL;
			FreeImage_ConvertToRawBits_t  FreeImage_ConvertToRawBits = NULL;

			if (hFreeImageLib)
			{
				bool exportsValid = true;

				//FreeImage_GetVersion = (FreeImage_GetVersion_t)s_GetProcAddressEx(hFreeImageLib, "_FreeImage_GetVersion@0", valid);
				FreeImage_GetWidth = (FreeImage_GetWidth_t)s_GetProcAddressEx(hFreeImageLib, "_FreeImage_GetWidth@4", exportsValid);
				FreeImage_GetHeight = (FreeImage_GetHeight_t)s_GetProcAddressEx(hFreeImageLib, "_FreeImage_GetHeight@4", exportsValid);
				FreeImage_Unload = (FreeImage_Unload_t)s_GetProcAddressEx(hFreeImageLib, "_FreeImage_Unload@4", exportsValid);
				FreeImage_ConvertToRawBits = (FreeImage_ConvertToRawBits_t)s_GetProcAddressEx(hFreeImageLib, "_FreeImage_ConvertToRawBits@32", exportsValid);

#ifdef UNICODE
				FreeImage_GetFileType = (FreeImage_GetFileType_t)s_GetProcAddressEx(hFreeImageLib, "_FreeImage_GetFileTypeU@8", exportsValid);
				FreeImage_GetFIFFromFilename = (FreeImage_GetFIFFromFilename_t)s_GetProcAddressEx(hFreeImageLib, "_FreeImage_GetFIFFromFilenameU@4", exportsValid);
				FreeImage_Load = (FreeImage_Load_t)s_GetProcAddressEx(hFreeImageLib, "_FreeImage_LoadU@12", exportsValid);
#else
				FreeImage_GetFileType = (FreeImage_GetFileType_t)s_GetProcAddressEx(hFreeImageLib, "_FreeImage_GetFileType@8", exportsValid);
				FreeImage_GetFIFFromFilename = (FreeImage_GetFIFFromFilename_t)s_GetProcAddressEx(hFreeImageLib, "_FreeImage_GetFIFFromFilename@4", exportsValid);
				FreeImage_Load = (FreeImage_Load_t)s_GetProcAddressEx(hFreeImageLib, "_FreeImage_Load@12", exportsValid);
#endif

				//const char* version = FreeImage_GetVersion();

				// Check the DLL is using compatible exports
				if (exportsValid)
				{
					// Derive file type from file header.
					int fileType = FreeImage_GetFileType(sFilePathName.c_str(), 0);
					if (fileType < 0)
					{
						// No file header available, attempt to parse file name for extension.
						fileType = FreeImage_GetFIFFromFilename(sFilePathName.c_str());
					}

					// If we have a valid file type
					if (fileType >= 0)
					{
						void* dib = FreeImage_Load(fileType, sFilePathName.c_str(), 0);

						if (dib)
						{
							unsigned width = FreeImage_GetWidth(dib);
							unsigned height = FreeImage_GetHeight(dib);

							// Create a GDI+ bitmap to load into...
							pBitmap = new Bitmap(width, height, PixelFormat32bppARGB);

							if (pBitmap && pBitmap->GetLastStatus() == Ok)
							{
								// Write & convert the loaded data into the GDI+ Bitmap
								Rect rect(0, 0, width, height);
								BitmapData bitmapData;
								if (pBitmap->LockBits(&rect, ImageLockModeWrite, PixelFormat32bppARGB, &bitmapData) == Ok)
								{
									FreeImage_ConvertToRawBits((BYTE*)bitmapData.Scan0, dib, bitmapData.Stride, 32, 0xff << RED_SHIFT, 0xff << GREEN_SHIFT, 0xff << BLUE_SHIFT, FALSE);

									pBitmap->UnlockBits(&bitmapData);

									m_Width = width;
									m_Height = height;
									bResult = true;
								}
								else    // Failed to lock the destination Bitmap
								{
									delete pBitmap;
									pBitmap = NULL;
								}
							}
							else    // Bitmap allocation failed
							{
								delete pBitmap;
								pBitmap = NULL;
							}

							FreeImage_Unload(dib);
							dib = NULL;
						}
					}
				}

				FreeLibrary(hFreeImageLib);
				hFreeImageLib = NULL;
			}
		}
	}
Пример #20
0
FIBITMAP * DLL_CALLCONV
FreeImage_ConvertToFloat(FIBITMAP *dib) {
	FIBITMAP *src = NULL;
	FIBITMAP *dst = NULL;

	if(!FreeImage_HasPixels(dib)) return NULL;

	FREE_IMAGE_TYPE src_type = FreeImage_GetImageType(dib);

	// check for allowed conversions 
	switch(src_type) {
		case FIT_BITMAP:
		{
			// allow conversion from 8-bit
			if((FreeImage_GetBPP(dib) == 8) && (FreeImage_GetColorType(dib) == FIC_MINISBLACK)) {
				src = dib;
			} else {
				src = FreeImage_ConvertToGreyscale(dib);
				if(!src) return NULL;
			}
			break;
		}
		case FIT_UINT16:
		case FIT_RGB16:
		case FIT_RGBA16:
		case FIT_RGBF:
		case FIT_RGBAF:
			src = dib;
			break;
		case FIT_FLOAT:
			// float type : clone the src
			return FreeImage_Clone(dib);
		default:
			return NULL;
	}

	// allocate dst image

	const unsigned width = FreeImage_GetWidth(src);
	const unsigned height = FreeImage_GetHeight(src);

	dst = FreeImage_AllocateT(FIT_FLOAT, width, height);
	if(!dst) {
		if(src != dib) {
			FreeImage_Unload(src);
		}
		return NULL;
	}

	// copy metadata from src to dst
	FreeImage_CloneMetadata(dst, src);

	// convert from src type to float

	const unsigned src_pitch = FreeImage_GetPitch(src);
	const unsigned dst_pitch = FreeImage_GetPitch(dst);

	const BYTE *src_bits = (BYTE*)FreeImage_GetBits(src);
	BYTE *dst_bits = (BYTE*)FreeImage_GetBits(dst);

	switch(src_type) {
		case FIT_BITMAP:
		{
			for(unsigned y = 0; y < height; y++) {
				const BYTE *src_pixel = (BYTE*)src_bits;
				float *dst_pixel = (float*)dst_bits;
				for(unsigned x = 0; x < width; x++) {
					// convert and scale to the range [0..1]
					dst_pixel[x] = (float)(src_pixel[x]) / 255;
				}
				src_bits += src_pitch;
				dst_bits += dst_pitch;
			}
		}
		break;

		case FIT_UINT16:
		{
			for(unsigned y = 0; y < height; y++) {
				const WORD *src_pixel = (WORD*)src_bits;
				float *dst_pixel = (float*)dst_bits;

				for(unsigned x = 0; x < width; x++) {
					// convert and scale to the range [0..1]
					dst_pixel[x] = (float)(src_pixel[x]) / 65535;
				}
				src_bits += src_pitch;
				dst_bits += dst_pitch;
			}
		}
		break;

		case FIT_RGB16:
		{
			for(unsigned y = 0; y < height; y++) {
				const FIRGB16 *src_pixel = (FIRGB16*)src_bits;
				float *dst_pixel = (float*)dst_bits;

				for(unsigned x = 0; x < width; x++) {
					// convert and scale to the range [0..1]
					dst_pixel[x] = LUMA_REC709(src_pixel[x].red, src_pixel[x].green, src_pixel[x].blue) / 65535.0F;
				}
				src_bits += src_pitch;
				dst_bits += dst_pitch;
			}
		}
		break;

		case FIT_RGBA16:
		{
			for(unsigned y = 0; y < height; y++) {
				const FIRGBA16 *src_pixel = (FIRGBA16*)src_bits;
				float *dst_pixel = (float*)dst_bits;

				for(unsigned x = 0; x < width; x++) {
					// convert and scale to the range [0..1]
					dst_pixel[x] = LUMA_REC709(src_pixel[x].red, src_pixel[x].green, src_pixel[x].blue) / 65535.0F;
				}
				src_bits += src_pitch;
				dst_bits += dst_pitch;
			}
		}
		break;

		case FIT_RGBF:
		{
			for(unsigned y = 0; y < height; y++) {
				const FIRGBF *src_pixel = (FIRGBF*)src_bits;
				float *dst_pixel = (float*)dst_bits;

				for(unsigned x = 0; x < width; x++) {
					// convert (assume pixel values are in the range [0..1])
					dst_pixel[x] = LUMA_REC709(src_pixel[x].red, src_pixel[x].green, src_pixel[x].blue);
				}
				src_bits += src_pitch;
				dst_bits += dst_pitch;
			}
		}
		break;

		case FIT_RGBAF:
		{
			for(unsigned y = 0; y < height; y++) {
				const FIRGBAF *src_pixel = (FIRGBAF*)src_bits;
				float *dst_pixel = (float*)dst_bits;

				for(unsigned x = 0; x < width; x++) {
					// convert (assume pixel values are in the range [0..1])
					dst_pixel[x] = LUMA_REC709(src_pixel[x].red, src_pixel[x].green, src_pixel[x].blue);
				}
				src_bits += src_pitch;
				dst_bits += dst_pitch;
			}
		}
		break;
	}

	if(src != dib) {
		FreeImage_Unload(src);
	}

	return dst;
}
Пример #21
0
static void *bg_next_frame(void *data)
{
  struct imv_loader *ldr = data;

  pthread_mutex_lock(&ldr->lock);
  int num_frames = ldr->num_frames;
  if(num_frames < 2) {
    pthread_mutex_unlock(&ldr->lock);
    return NULL;
  }

  FITAG *tag = NULL;
  char disposal_method = 0;
  int frame_time = 0;
  short top = 0;
  short left = 0;

  ldr->cur_frame = ldr->next_frame;
  ldr->next_frame = (ldr->cur_frame + 1) % ldr->num_frames;
  FIBITMAP *frame = FreeImage_LockPage(ldr->mbmp, ldr->cur_frame);
  FIBITMAP *frame32 = FreeImage_ConvertTo32Bits(frame);

  /* First frame is always going to use the raw frame */
  if(ldr->cur_frame > 0) {
    FreeImage_GetMetadata(FIMD_ANIMATION, frame, "DisposalMethod", &tag);
    if(FreeImage_GetTagValue(tag)) {
      disposal_method = *(char*)FreeImage_GetTagValue(tag);
    }
  }

  FreeImage_GetMetadata(FIMD_ANIMATION, frame, "FrameLeft", &tag);
  if(FreeImage_GetTagValue(tag)) {
    left = *(short*)FreeImage_GetTagValue(tag);
  }

  FreeImage_GetMetadata(FIMD_ANIMATION, frame, "FrameTop", &tag);
  if(FreeImage_GetTagValue(tag)) {
    top = *(short*)FreeImage_GetTagValue(tag);
  }

  FreeImage_GetMetadata(FIMD_ANIMATION, frame, "FrameTime", &tag);
  if(FreeImage_GetTagValue(tag)) {
    frame_time = *(int*)FreeImage_GetTagValue(tag);
  }

  /* some gifs don't provide a frame time at all */
  if(frame_time == 0) {
    frame_time = 100;
  }
  ldr->frame_time += frame_time * 0.001;

  FreeImage_UnlockPage(ldr->mbmp, frame, 0);

  /* If this frame is inset, we need to expand it for compositing */
  if(ldr->width != (int)FreeImage_GetWidth(frame32) ||
     ldr->height != (int)FreeImage_GetHeight(frame32)) {
    FIBITMAP *expanded = FreeImage_Allocate(ldr->width, ldr->height, 32, 0,0,0);
    FreeImage_Paste(expanded, frame32, left, top, 255);
    FreeImage_Unload(frame32);
    frame32 = expanded;
  }

  switch(disposal_method) {
    case 0: /* nothing specified, fall through to compositing */
    case 1: /* composite over previous frame */
      if(ldr->bmp && ldr->cur_frame > 0) {
        FIBITMAP *bg_frame = FreeImage_ConvertTo24Bits(ldr->bmp);
        FreeImage_Unload(ldr->bmp);
        FIBITMAP *comp = FreeImage_Composite(frame32, 1, NULL, bg_frame);
        FreeImage_Unload(bg_frame);
        FreeImage_Unload(frame32);
        ldr->bmp = comp;
      } else {
        /* No previous frame, just render directly */
        if(ldr->bmp) {
          FreeImage_Unload(ldr->bmp);
        }
        ldr->bmp = frame32;
      }
      break;
    case 2: /* TODO - set to background, composite over that */
      if(ldr->bmp) {
        FreeImage_Unload(ldr->bmp);
      }
      ldr->bmp = frame32;
      break;
    case 3: /* TODO - restore to previous content */
      if(ldr->bmp) {
        FreeImage_Unload(ldr->bmp);
      }
      ldr->bmp = frame32;
      break;
  }

  if(ldr->out_bmp) {
    FreeImage_Unload(ldr->out_bmp);
  }
  ldr->out_bmp = FreeImage_Clone(ldr->bmp);

  pthread_mutex_unlock(&ldr->lock);
  return NULL;
}
Пример #22
0
CImageDataLoader::CImageData::CImageData(IDataStream* pData)
{
	if(pData->IsValid())
	{
		static bool init = false;
		if(!init)
		{
			init = true;
			
			TLS_data backup = *TLS::getData();
			TLS::getData()->domain_ptr = nullptr;
			TLS::getData()->domain_guid = guidNull;
			FreeImage_Initialise();
			*TLS::getData() = backup;
		}

		TLS_data backup = *TLS::getData();
		TLS::getData()->domain_ptr = nullptr;
		TLS::getData()->domain_guid = guidNull;
		FIBITMAP* fibitmap = FreeImage_LoadFromHandle(FIF_PNG,&ImageLoaderIO,(fi_handle)pData);
		*TLS::getData() = backup;

		if(fibitmap)
		{
			_Width = FreeImage_GetWidth(fibitmap);
			_Height = FreeImage_GetHeight(fibitmap);
			_Format = R8G8B8A8;
			_Data = new u8[_Width*_Height*sizeof(u32)];
			for(int iy =0; iy < _Height; ++iy)
				for(int ix =0; ix < _Width; ++ix)
				{
					RGBQUAD color;
					FreeImage_GetPixelColor(fibitmap,ix,iy,&color);
					((u32*)_Data)[iy*_Width+ix] = ((u32)color.rgbRed << 0) | ((u32)color.rgbGreen << 8) | ((u32)color.rgbBlue << 16) | ((u32)0xff << 24);
				}
			
			TLS_data backup = *TLS::getData();
			TLS::getData()->domain_ptr = nullptr;
			TLS::getData()->domain_guid = guidNull;
	
			FreeImage_Unload(fibitmap);

			*TLS::getData() = backup;

			_Levels = 1;
			return;
		}
		pData->Seek(0,IDataStream::ORIGIN_BEGINNING);
		if(TryLoadBLP(pData))
			return;
		
		pData->Seek(0,IDataStream::ORIGIN_BEGINNING);
		/*
		SparseVirtualTextureFile hsvt;
		if(hsvt.Open(pData))
		{
			_Width = 5120;
			_Height = 5120;
			_Format = R8G8B8A8;
			_Levels = 1;
			_Data = new u8[_Width*_Height*sizeof(u32)];


			hsvt.ReadImageFromVirtualTexture(0,0,_Width,_Height,_Data,6);


			return;
		}
		
		pData->Seek(0,IDataStream::ORIGIN_BEGINNING);*/


	}

	// loading failed
	_Width = 256;
	_Height = 256;
	_Format = R8G8B8A8;
	_Levels = 1;
	_Data = new u8[_Width*_Height*sizeof(u32)];
	for(int iy =0; iy < _Height; ++iy)
		for(int ix =0; ix < _Width; ++ix)
			((u32*)_Data)[iy*_Width+ix] = ((1-((iy/64)+(ix/64))%2) * 0x00ffffff) | 0xff000000;
}
Пример #23
0
static BOOL DLL_CALLCONV
Save(FreeImageIO *io, FIBITMAP *dib, fi_handle handle, int page, int flags, void *data) {
	png_structp png_ptr = nullptr;
	png_infop info_ptr;
	png_colorp palette = NULL;
	png_uint_32 width, height;
	BOOL has_alpha_channel = FALSE;

	RGBQUAD *pal;					// pointer to dib palette
	int bit_depth, pixel_depth;		// pixel_depth = bit_depth * channels
	int palette_entries;
	int	interlace_type;

	fi_ioStructure fio;
    fio.s_handle = handle;
	fio.s_io = io;

	if ((dib) && (handle)) {
		try {
			// create the chunk manage structure

			png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, (png_voidp)NULL, error_handler, warning_handler);

			if (!png_ptr)  {
				return FALSE;
			}

			// allocate/initialize the image information data.

			info_ptr = png_create_info_struct(png_ptr);

			if (!info_ptr)  {
				png_destroy_write_struct(&png_ptr,  (png_infopp)NULL);
				return FALSE;
			}

			// Set error handling.  REQUIRED if you aren't supplying your own
			// error handling functions in the png_create_write_struct() call.

			if (setjmp(png_jmpbuf(png_ptr)))  {
				// if we get here, we had a problem reading the file

				png_destroy_write_struct(&png_ptr, &info_ptr);

				return FALSE;
			}

			// init the IO
            
			png_set_write_fn(png_ptr, &fio, _WriteProc, _FlushProc);

			// set physical resolution

			png_uint_32 res_x = (png_uint_32)FreeImage_GetDotsPerMeterX(dib);
			png_uint_32 res_y = (png_uint_32)FreeImage_GetDotsPerMeterY(dib);

			if ((res_x > 0) && (res_y > 0))  {
				png_set_pHYs(png_ptr, info_ptr, res_x, res_y, PNG_RESOLUTION_METER);
			}
	
			// Set the image information here.  Width and height are up to 2^31,
			// bit_depth is one of 1, 2, 4, 8, or 16, but valid values also depend on
			// the color_type selected. color_type is one of PNG_COLOR_TYPE_GRAY,
			// PNG_COLOR_TYPE_GRAY_ALPHA, PNG_COLOR_TYPE_PALETTE, PNG_COLOR_TYPE_RGB,
			// or PNG_COLOR_TYPE_RGB_ALPHA.  interlace is either PNG_INTERLACE_NONE or
			// PNG_INTERLACE_ADAM7, and the compression_type and filter_type MUST
			// currently be PNG_COMPRESSION_TYPE_BASE and PNG_FILTER_TYPE_BASE. REQUIRED

			width = FreeImage_GetWidth(dib);
			height = FreeImage_GetHeight(dib);
			pixel_depth = FreeImage_GetBPP(dib);

			BOOL bInterlaced = FALSE;
			if( (flags & PNG_INTERLACED) == PNG_INTERLACED) {
				interlace_type = PNG_INTERLACE_ADAM7;
				bInterlaced = TRUE;
			} else {
				interlace_type = PNG_INTERLACE_NONE;
			}

			// set the ZLIB compression level or default to PNG default compression level (ZLIB level = 6)
			int zlib_level = flags & 0x0F;
			if((zlib_level >= 1) && (zlib_level <= 9)) {
				png_set_compression_level(png_ptr, zlib_level);
			} else if((flags & PNG_Z_NO_COMPRESSION) == PNG_Z_NO_COMPRESSION) {
				png_set_compression_level(png_ptr, Z_NO_COMPRESSION);
			}

			// filtered strategy works better for high color images
			if(pixel_depth >= 16){
				png_set_compression_strategy(png_ptr, Z_FILTERED);
				png_set_filter(png_ptr, 0, PNG_FILTER_NONE|PNG_FILTER_SUB|PNG_FILTER_PAETH);
			} else {
				png_set_compression_strategy(png_ptr, Z_DEFAULT_STRATEGY);
			}

			FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(dib);
			if(image_type == FIT_BITMAP) {
				// standard image type
				bit_depth = (pixel_depth > 8) ? 8 : pixel_depth;
			} else {
				// 16-bit greyscale or 16-bit RGB(A)
				bit_depth = 16;
			}

			// check for transparent images
			BOOL bIsTransparent = 
				(image_type == FIT_BITMAP) && FreeImage_IsTransparent(dib) && (FreeImage_GetTransparencyCount(dib) > 0) ? TRUE : FALSE;

			switch (FreeImage_GetColorType(dib)) {
				case FIC_MINISWHITE:
					if(!bIsTransparent) {
						// Invert monochrome files to have 0 as black and 1 as white (no break here)
						png_set_invert_mono(png_ptr);
					}
					// (fall through)

				case FIC_MINISBLACK:
					if(!bIsTransparent) {
						png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, 
							PNG_COLOR_TYPE_GRAY, interlace_type, 
							PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
						break;
					}
					// If a monochrome image is transparent, save it with a palette
					// (fall through)

				case FIC_PALETTE:
				{
					png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, 
						PNG_COLOR_TYPE_PALETTE, interlace_type, 
						PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);

					// set the palette

					palette_entries = 1 << bit_depth;
					palette = (png_colorp)png_malloc(png_ptr, palette_entries * sizeof (png_color));
					pal = FreeImage_GetPalette(dib);

					for (int i = 0; i < palette_entries; i++) {
						palette[i].red   = pal[i].rgbRed;
						palette[i].green = pal[i].rgbGreen;
						palette[i].blue  = pal[i].rgbBlue;
					}
					
					png_set_PLTE(png_ptr, info_ptr, palette, palette_entries);

					// You must not free palette here, because png_set_PLTE only makes a link to
					// the palette that you malloced.  Wait until you are about to destroy
					// the png structure.

					break;
				}

				case FIC_RGBALPHA :
					has_alpha_channel = TRUE;

					png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, 
						PNG_COLOR_TYPE_RGBA, interlace_type, 
						PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);

#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_BGR
					// flip BGR pixels to RGB
					if(image_type == FIT_BITMAP) {
						png_set_bgr(png_ptr);
					}
#endif
					break;
	
				case FIC_RGB:
					png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, 
						PNG_COLOR_TYPE_RGB, interlace_type, 
						PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);

#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_BGR
					// flip BGR pixels to RGB
					if(image_type == FIT_BITMAP) {
						png_set_bgr(png_ptr);
					}
#endif
					break;
					
				case FIC_CMYK:
					break;
			}

			// write possible ICC profile

			FIICCPROFILE *iccProfile = FreeImage_GetICCProfile(dib);
			if (iccProfile->size && iccProfile->data) {
				png_set_iCCP(png_ptr, info_ptr, "Embedded Profile", 0, (png_const_bytep)iccProfile->data, iccProfile->size);
			}

			// write metadata

			WriteMetadata(png_ptr, info_ptr, dib);

			// Optional gamma chunk is strongly suggested if you have any guess
			// as to the correct gamma of the image.
			// png_set_gAMA(png_ptr, info_ptr, gamma);

			// set the transparency table

			if (bIsTransparent) {
				png_set_tRNS(png_ptr, info_ptr, FreeImage_GetTransparencyTable(dib), FreeImage_GetTransparencyCount(dib), NULL);
			}

			// set the background color

			if(FreeImage_HasBackgroundColor(dib)) {
				png_color_16 image_background;
				RGBQUAD rgbBkColor;

				FreeImage_GetBackgroundColor(dib, &rgbBkColor);
				memset(&image_background, 0, sizeof(png_color_16));
				image_background.blue  = rgbBkColor.rgbBlue;
				image_background.green = rgbBkColor.rgbGreen;
				image_background.red   = rgbBkColor.rgbRed;
				image_background.index = rgbBkColor.rgbReserved;

				png_set_bKGD(png_ptr, info_ptr, &image_background);
			}
			
			// Write the file header information.

			png_write_info(png_ptr, info_ptr);

			// write out the image data

#ifndef FREEIMAGE_BIGENDIAN
			if (bit_depth == 16) {
				// turn on 16 bit byte swapping
				png_set_swap(png_ptr);
			}
#endif

			int number_passes = 1;
			if (bInterlaced) {
				number_passes = png_set_interlace_handling(png_ptr);
			}

			if ((pixel_depth == 32) && (!has_alpha_channel)) {
				BYTE *buffer = (BYTE *)malloc(width * 3);

				// transparent conversion to 24-bit
				// the number of passes is either 1 for non-interlaced images, or 7 for interlaced images
				for (int pass = 0; pass < number_passes; pass++) {
					for (png_uint_32 k = 0; k < height; k++) {
						FreeImage_ConvertLine32To24(buffer, FreeImage_GetScanLine(dib, height - k - 1), width);
						png_write_row(png_ptr, buffer);
					}
				}
				free(buffer);
			} else {
				// the number of passes is either 1 for non-interlaced images, or 7 for interlaced images
				for (int pass = 0; pass < number_passes; pass++) {
					for (png_uint_32 k = 0; k < height; k++) {
						png_write_row(png_ptr, FreeImage_GetScanLine(dib, height - k - 1));
					}
				}
			}

			// It is REQUIRED to call this to finish writing the rest of the file
			// Bug with png_flush

			png_write_end(png_ptr, info_ptr);

			// clean up after the write, and free any memory allocated
			if (palette) {
				png_free(png_ptr, palette);
			}

			png_destroy_write_struct(&png_ptr, &info_ptr);

			return TRUE;

		} catch (const char *text) {
			if(png_ptr) {
				png_destroy_write_struct(&png_ptr, &info_ptr);
			}
			FreeImage_OutputMessageProc(s_format_id, text);
		}
	}

	return FALSE;
}
Пример #24
0
/**
   Write a FIBITMAP to a JNG stream
   @param format_id ID of the caller
   @param io Stream i/o functions
   @param dib Image to be saved
   @param handle Stream handle
   @param flags Saving flags
   @return Returns TRUE if successful, returns FALSE otherwise
*/
BOOL
mng_WriteJNG(int format_id, FreeImageIO *io, FIBITMAP *dib, fi_handle handle, int flags) {
    DWORD jng_width = 0;
    DWORD jng_height = 0;
    BYTE jng_color_type = 0;
    BYTE jng_image_sample_depth = 8;
    BYTE jng_image_compression_method = 8;  //  8: ISO-10918-1 Huffman-coded baseline JPEG.
    BYTE jng_image_interlace_method = 0;

    BYTE jng_alpha_sample_depth = 0;
    BYTE jng_alpha_compression_method = 0;
    BYTE jng_alpha_filter_method = 0;
    BYTE jng_alpha_interlace_method = 0;

    BYTE buffer[16];

    FIMEMORY *hJngMemory = NULL;
    FIMEMORY *hJpegMemory = NULL;
    FIMEMORY *hPngMemory = NULL;

    FIBITMAP *dib_rgb = NULL;
    FIBITMAP *dib_alpha = NULL;

    if(!dib || (FreeImage_GetImageType(dib) != FIT_BITMAP)) {
        return FALSE;
    }

    unsigned bpp = FreeImage_GetBPP(dib);

    switch(bpp) {
        case 8:
            if(FreeImage_GetColorType(dib) == FIC_MINISBLACK) {
                dib_rgb = dib;
                jng_color_type = MNG_COLORTYPE_JPEGGRAY;
            } else {
                // JPEG plugin will convert other types (FIC_MINISWHITE, FIC_PALETTE) to 24-bit on the fly
                //dib_rgb = FreeImage_ConvertTo24Bits(dib);
                dib_rgb = dib;
                jng_color_type = MNG_COLORTYPE_JPEGCOLOR;

            }
            break;
        case 24:
            dib_rgb = dib;
            jng_color_type = MNG_COLORTYPE_JPEGCOLOR;
            break;
        case 32:
            dib_rgb = FreeImage_ConvertTo24Bits(dib);
            jng_color_type = MNG_COLORTYPE_JPEGCOLORA;
            jng_alpha_sample_depth = 8;
            break;
        default:
            return FALSE;
    }

    jng_width = (DWORD)FreeImage_GetWidth(dib);
    jng_height = (DWORD)FreeImage_GetHeight(dib);

    try {
        hJngMemory = FreeImage_OpenMemory();

        // --- write JNG file signature ---
        FreeImage_WriteMemory(g_jng_signature, 1, 8, hJngMemory);

        // --- write a JHDR chunk ---
        SwapLong(&jng_width);
        SwapLong(&jng_height);
        memcpy(&buffer[0], &jng_width, 4);
        memcpy(&buffer[4], &jng_height, 4);
        SwapLong(&jng_width);
        SwapLong(&jng_height);
        buffer[8] = jng_color_type;
        buffer[9] = jng_image_sample_depth;
        buffer[10] = jng_image_compression_method;
        buffer[11] = jng_image_interlace_method;
        buffer[12] = jng_alpha_sample_depth;
        buffer[13] = jng_alpha_compression_method;
        buffer[14] = jng_alpha_filter_method;
        buffer[15] = jng_alpha_interlace_method;
        mng_WriteChunk(mng_JHDR, &buffer[0], 16, hJngMemory);

        // --- write a sequence of JDAT chunks ---
        hJpegMemory = FreeImage_OpenMemory();
        flags |= JPEG_BASELINE;
        if(!FreeImage_SaveToMemory(FIF_JPEG, dib_rgb, hJpegMemory, flags)) {
            throw (const char*)NULL;
        }
        if(dib_rgb != dib) {
            FreeImage_Unload(dib_rgb);
            dib_rgb = NULL;
        }
        {
            BYTE *jpeg_data = NULL;
            DWORD size_in_bytes = 0;

            // get a pointer to the stream buffer
            FreeImage_AcquireMemory(hJpegMemory, &jpeg_data, &size_in_bytes);
            // write chunks
            for(DWORD k = 0; k < size_in_bytes;) {
                DWORD bytes_left = size_in_bytes - k;
                DWORD chunk_size = MIN(JPEG_CHUNK_SIZE, bytes_left);
                mng_WriteChunk(mng_JDAT, &jpeg_data[k], chunk_size, hJngMemory);
                k += chunk_size;
            }
        }
        FreeImage_CloseMemory(hJpegMemory);
        hJpegMemory = NULL;

        // --- write alpha layer as a sequence of IDAT chunk ---
        if((bpp == 32) && (jng_color_type == MNG_COLORTYPE_JPEGCOLORA)) {
            dib_alpha = FreeImage_GetChannel(dib, FICC_ALPHA);

            hPngMemory = FreeImage_OpenMemory();
            if(!FreeImage_SaveToMemory(FIF_PNG, dib_alpha, hPngMemory, PNG_DEFAULT)) {
                throw (const char*)NULL;
            }
            FreeImage_Unload(dib_alpha);
            dib_alpha = NULL;
            // get the IDAT chunk
            {
                BOOL bResult = FALSE;
                DWORD start_pos = 0;
                DWORD next_pos = 0;
                long offset = 8;

                do {
                    // find the next IDAT chunk from 'offset' position
                    bResult = mng_FindChunk(hPngMemory, mng_IDAT, offset, &start_pos, &next_pos);
                    if(!bResult) break;

                    BYTE *png_data = NULL;
                    DWORD size_in_bytes = 0;

                    // get a pointer to the stream buffer
                    FreeImage_AcquireMemory(hPngMemory, &png_data, &size_in_bytes);
                    // write the IDAT chunk
                    mng_WriteChunk(mng_IDAT, &png_data[start_pos+8], next_pos - start_pos - 12, hJngMemory);

                    offset = next_pos;

                } while(bResult);
            }

            FreeImage_CloseMemory(hPngMemory);
            hPngMemory = NULL;
        }

        // --- write a IEND chunk ---
        mng_WriteChunk(mng_IEND, NULL, 0, hJngMemory);

        // write the JNG on output stream
        {
            BYTE *jng_data = NULL;
            DWORD size_in_bytes = 0;
            FreeImage_AcquireMemory(hJngMemory, &jng_data, &size_in_bytes);
            io->write_proc(jng_data, 1, size_in_bytes, handle);
        }

        FreeImage_CloseMemory(hJngMemory);
        FreeImage_CloseMemory(hJpegMemory);
        FreeImage_CloseMemory(hPngMemory);

        return TRUE;

    } catch(const char *text) {
        FreeImage_CloseMemory(hJngMemory);
        FreeImage_CloseMemory(hJpegMemory);
        FreeImage_CloseMemory(hPngMemory);
        if(dib_rgb && (dib_rgb != dib)) {
            FreeImage_Unload(dib_rgb);
        }
        FreeImage_Unload(dib_alpha);
        if(text) {
            FreeImage_OutputMessageProc(format_id, text);
        }
        return FALSE;
    }
}
Пример #25
0
static BOOL DLL_CALLCONV
Save(FreeImageIO *io, FIBITMAP *dib, fi_handle handle, int page, int flags, void *data) {
	const char *channel_name[4] = { "R", "G", "B", "A" };
	BOOL bIsFlipped = FALSE;
	half *halfData = NULL;

	if(!dib || !handle) return FALSE;

	try {
		// check for EXR_LC compression and verify that the format is RGB
		if((flags & EXR_LC) == EXR_LC) {
			FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(dib);
			if(((image_type != FIT_RGBF) && (image_type != FIT_RGBAF)) || ((flags & EXR_FLOAT) == EXR_FLOAT)) {
				THROW (Iex::IoExc, "EXR_LC compression is only available with RGB[A]F images");
			}
			if((FreeImage_GetWidth(dib) % 2) || (FreeImage_GetHeight(dib) % 2)) {
				THROW (Iex::IoExc, "EXR_LC compression only works when the width and height are a multiple of 2");
			}
		}

		// wrap the FreeImage IO stream
		C_OStream ostream(io, handle);

		// compression
		Imf::Compression compress;
		if((flags & EXR_NONE) == EXR_NONE) {
			// no compression
			compress = Imf::NO_COMPRESSION;
		} else if((flags & EXR_ZIP) == EXR_ZIP) {
			// zlib compression, in blocks of 16 scan lines
			compress = Imf::ZIP_COMPRESSION;
		} else if((flags & EXR_PIZ) == EXR_PIZ) {
			// piz-based wavelet compression
			compress = Imf::PIZ_COMPRESSION;
		} else if((flags & EXR_PXR24) == EXR_PXR24) {
			// lossy 24-bit float compression
			compress = Imf::PXR24_COMPRESSION;
		} else if((flags & EXR_B44) == EXR_B44) {
			// lossy 44% float compression
			compress = Imf::B44_COMPRESSION;
		} else {
			// default value
			compress = Imf::PIZ_COMPRESSION;
		}

		// create the header
		int width  = FreeImage_GetWidth(dib);
		int height = FreeImage_GetHeight(dib);
		int dx = 0, dy = 0;

		Imath::Box2i dataWindow (Imath::V2i (0, 0), Imath::V2i (width - 1, height - 1));
		Imath::Box2i displayWindow (Imath::V2i (-dx, -dy), Imath::V2i (width - dx - 1, height - dy - 1));

		Imf::Header header = Imf::Header(displayWindow, dataWindow, 1, 
			Imath::V2f(0,0), 1, 
			Imf::INCREASING_Y, compress);        		

		// handle thumbnail
		SetPreviewImage(dib, header);
		
		// check for EXR_LC compression
		if((flags & EXR_LC) == EXR_LC) {
			return SaveAsEXR_LC(ostream, dib, header, width, height);
		}

		// output pixel type
		Imf::PixelType pixelType;
		if((flags & EXR_FLOAT) == EXR_FLOAT) {
			pixelType = Imf::FLOAT;	// save as float data type
		} else {
			// default value
			pixelType = Imf::HALF;	// save as half data type
		}

		// check the data type and number of channels
		int components = 0;
		FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(dib);
		switch(image_type) {
			case FIT_FLOAT:
				components = 1;
				// insert luminance channel
				header.channels().insert ("Y", Imf::Channel(pixelType));
				break;
			case FIT_RGBF:
				components = 3;
				for(int c = 0; c < components; c++) {
					// insert R, G and B channels
					header.channels().insert (channel_name[c], Imf::Channel(pixelType));
				}
				break;
			case FIT_RGBAF:
				components = 4;
				for(int c = 0; c < components; c++) {
					// insert R, G, B and A channels
					header.channels().insert (channel_name[c], Imf::Channel(pixelType));
				}
				break;
			default:
				THROW (Iex::ArgExc, "Cannot save: invalid data type.\nConvert the image to float before saving as OpenEXR.");
		}

		// build a frame buffer (i.e. what we have on input)
		Imf::FrameBuffer frameBuffer;

		BYTE *bits = NULL;	// pointer to our pixel buffer
		size_t bytespp = 0;	// size of our pixel in bytes
		size_t bytespc = 0;	// size of our pixel component in bytes
		unsigned pitch = 0;	// size of our yStride in bytes


		if(pixelType == Imf::HALF) {
			// convert from float to half
			halfData = new(std::nothrow) half[width * height * components];
			if(!halfData) THROW (Iex::NullExc, FI_MSG_ERROR_MEMORY);

			for(int y = 0; y < height; y++) {
				float *src_bits = (float*)FreeImage_GetScanLine(dib, height - 1 - y);
				half *dst_bits = halfData + y * width * components;
				for(int x = 0; x < width; x++) {
					for(int c = 0; c < components; c++) {
						dst_bits[c] = src_bits[c];
					}
					src_bits += components;
					dst_bits += components;
				}
			}
			bits = (BYTE*)halfData;
			bytespc = sizeof(half);
			bytespp = sizeof(half) * components;
			pitch = sizeof(half) * width * components;
		} else if(pixelType == Imf::FLOAT) {
			// invert dib scanlines
			bIsFlipped = FreeImage_FlipVertical(dib);
		
			bits = FreeImage_GetBits(dib);
			bytespc = sizeof(float);
			bytespp = sizeof(float) * components;
			pitch = FreeImage_GetPitch(dib);
		}

		if(image_type == FIT_FLOAT) {
			frameBuffer.insert ("Y",	// name
				Imf::Slice (pixelType,	// type
				(char*)(bits),			// base
				bytespp,				// xStride
				pitch));				// yStride
		} else if((image_type == FIT_RGBF) || (image_type == FIT_RGBAF)) {			
			for(int c = 0; c < components; c++) {
				char *channel_base = (char*)(bits) + c*bytespc;
				frameBuffer.insert (channel_name[c],// name
					Imf::Slice (pixelType,			// type
					channel_base,					// base
					bytespp,	// xStride
					pitch));	// yStride
			}
		}

		// write the data
		Imf::OutputFile file (ostream, header);
		file.setFrameBuffer (frameBuffer);
		file.writePixels (height);

		if(halfData != NULL) delete[] halfData;
		if(bIsFlipped) {
			// invert dib scanlines
			FreeImage_FlipVertical(dib);
		}

		return TRUE;

	} catch(Iex::BaseExc & e) {
		if(halfData != NULL) delete[] halfData;
		if(bIsFlipped) {
			// invert dib scanlines
			FreeImage_FlipVertical(dib);
		}

		FreeImage_OutputMessageProc(s_format_id, e.what());

		return FALSE;
	}	
}
Пример #26
0
void putBmpIntoPixels(FIBITMAP * bmp, ofPixels_<PixelType> &pix, bool swapForLittleEndian = true) {
	// convert to correct type depending on type of input bmp and PixelType
	FIBITMAP* bmpConverted = nullptr;
	FREE_IMAGE_TYPE imgType = FreeImage_GetImageType(bmp);
	if(sizeof(PixelType)==1 &&
		(FreeImage_GetColorType(bmp) == FIC_PALETTE || FreeImage_GetBPP(bmp) < 8
		||  imgType!=FIT_BITMAP)) {
		if(FreeImage_IsTransparent(bmp)) {
			bmpConverted = FreeImage_ConvertTo32Bits(bmp);
		} else {
			bmpConverted = FreeImage_ConvertTo24Bits(bmp);
		}
		bmp = bmpConverted;
	}else if(sizeof(PixelType)==2 && imgType!=FIT_UINT16 && imgType!=FIT_RGB16 && imgType!=FIT_RGBA16){
		if(FreeImage_IsTransparent(bmp)) {
			bmpConverted = FreeImage_ConvertToType(bmp,FIT_RGBA16);
		} else {
			bmpConverted = FreeImage_ConvertToType(bmp,FIT_RGB16);
		}
		bmp = bmpConverted;
	}else if(sizeof(PixelType)==4 && imgType!=FIT_FLOAT && imgType!=FIT_RGBF && imgType!=FIT_RGBAF){
		if(FreeImage_IsTransparent(bmp)) {
			bmpConverted = FreeImage_ConvertToType(bmp,FIT_RGBAF);
		} else {
			bmpConverted = FreeImage_ConvertToType(bmp,FIT_RGBF);
		}
		bmp = bmpConverted;
	}

	unsigned int width = FreeImage_GetWidth(bmp);
	unsigned int height = FreeImage_GetHeight(bmp);
	unsigned int bpp = FreeImage_GetBPP(bmp);
	unsigned int channels = (bpp / sizeof(PixelType)) / 8;
	unsigned int pitch = FreeImage_GetPitch(bmp);

	ofPixelFormat pixFormat;
	if(channels==1) pixFormat=OF_PIXELS_GRAY;
#ifdef TARGET_LITTLE_ENDIAN
	if(swapForLittleEndian){
		if(channels==3) pixFormat=OF_PIXELS_BGR;
		if(channels==4) pixFormat=OF_PIXELS_BGRA;
	}else{
		if(channels==3) pixFormat=OF_PIXELS_RGB;
		if(channels==4) pixFormat=OF_PIXELS_RGBA;
	}
#else
	if(channels==3) pixFormat=OF_PIXELS_RGB;
	if(channels==4) pixFormat=OF_PIXELS_RGBA;
#endif

	// ofPixels are top left, FIBITMAP is bottom left
	FreeImage_FlipVertical(bmp);
	
	unsigned char* bmpBits = FreeImage_GetBits(bmp);
	if(bmpBits != nullptr) {
		pix.setFromAlignedPixels((PixelType*) bmpBits, width, height, pixFormat, pitch);
	} else {
		ofLogError("ofImage") << "putBmpIntoPixels(): unable to set ofPixels from FIBITMAP";
	}
	
	if(bmpConverted != nullptr) {
		FreeImage_Unload(bmpConverted);
	}

#ifdef TARGET_LITTLE_ENDIAN
	if(swapForLittleEndian && sizeof(PixelType) == 1 && channels >=3 ) {
		pix.swapRgb();
	}
#endif
}
Пример #27
0
bool Engine::gameLoop()
{
	// set a variable to pass into the texture whatever
	//unsigned int texID;

	camera = Camera();

	// loop that will load all shaders
	for (int i = 0; i < texFiles.size(); i++)
	{
		// LOAD BEFORE GAME LOOP
		// this variable holds the texture file
		char* textureFile = texFiles[i];

		FIBITMAP* image = FreeImage_Load(FreeImage_GetFileType(textureFile, 0), textureFile);

		// check if load failed
		if (image == nullptr)
		{
			return false;
		}

		// convert the original image into a 32bit bmp
		FIBITMAP* image32Bit = FreeImage_ConvertTo32Bits(image);

		// unload the image from memory
		FreeImage_Unload(image);

		// generate and bind a new texture
		glGenTextures(1, &texIDs[i]);
		glBindTexture(GL_TEXTURE_2D, texIDs[i]);

		// upload the texture bytes
		glTexImage2D(GL_TEXTURE_2D, 0, GL_SRGB_ALPHA, FreeImage_GetWidth(image32Bit), FreeImage_GetHeight(image32Bit), 0, GL_BGRA, GL_UNSIGNED_BYTE, (void*)FreeImage_GetBits(image32Bit));

		// set min filter to linear
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

		// unload the image from RAM
		FreeImage_Unload(image32Bit);

		// unbind the texture when done
		glBindTexture(GL_TEXTURE_2D, 0);
	}

	int counter = 0;

	// values that will hold the mouse's position
	double mouseX;
	double mouseY;

	vec3 unit;

	// loop until the window is closed by the user
	while (!glfwWindowShouldClose(GLFWwindowPtr))
	{
		// update the game time
		prevFrameTime = currTime;
		currTime = glfwGetTime();
		deltaTime = currTime - prevFrameTime;

		// clear the canvas
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

		// this will apply an initial force whenever the cueball stops, representing the pool stick striking it
		float mag;
		vec3 mousePos;
		vec3 force;

		// calculate lighting
		vec3 lightLoc = vec3(0, 0, 4);

		// pass in the light to the shaders
		glUniform3f(5, lightLoc.x, lightLoc.y, lightLoc.z);
		glUniform3f(6, camera.transform.loc.x, camera.transform.loc.y, camera.transform.loc.z);

		// if the cue ball is not already moving or in play, then allow the player to move it
		if (keyIsDown[GLFW_MOUSE_BUTTON_LEFT] && !keyWasDown[GLFW_MOUSE_BUTTON_LEFT] && inPlay == false)
		{
			// reset the friction counter
			frictionCounter = 0;

			// gets the mouse location
			double mouseX;
			double mouseY;

			// method that gets the cursor location
			glfwGetCursorPos(GLFWwindowPtr, &mouseX, &mouseY);

			int width, height;

			glfwGetWindowSize(GLFWwindowPtr, &width, &height);

			//cout << mouseX << ", " << mouseY << endl;

			mouseX = (mouseX / 400) - 1;
			mouseY = (mouseY / 300) - 1;

			//cout << mouseX << ", " << mouseY << endl;

			// this is the vector that will hold the vector connecting the cue ball to the mouse
			vec3 ballToMouse = vec3(mouseX - objects[1].transform.loc.x, -mouseY - objects[1].transform.loc.y, 0);

			// find the magnitude
			mag = sqrt((pow(ballToMouse.x, 2)) + (pow(ballToMouse.y, 2)));

			// find the unit vector
			unit = vec3(ballToMouse.x / mag, ballToMouse.y / mag, 0);

			// this is the initial force
			force = vec3(unit.x * FORCE, unit.y * FORCE, 0);

			// multiply the initial force by that to find the final force vector
			objects[1].calcForces(force, deltaTime);

			// set the in Play attribute to true
			inPlay = true;
		}

		if (inPlay == true)
		{
			// calculate a frictional force
			//vec3 forceFriction = vec3(unit.x * FORCE_FRICTION, unit.y * FORCE_FRICTION, 0);

			for (int i = 1; i < objects.size(); i++)
			{
				objects[i].friction(deltaTime);
			}
			
			//cout << objects[1].getRigidBody().vel.x << " " << objects[1].getRigidBody().vel.y << endl;

			// set a counter
			//frictionCounter += FORCE_FRICTION;

			// a boolean that will check if all objects have stopped
			//bool allStopped = true;
			//
			//// if all objects have stopped, then set inPlay to false
			//for (int i = 1; i < objects.size(); i++)
			//{
			//	// if one object isn't stopped then set the boolean to false
			//	if (objects[i].rigidBody.vel != vec3(0, 0, 0))
			//	{
			//		allStopped = false;
			//	}
			//}
			//
			//if (allStopped == false)
			//{
			//	inPlay = false;
			//}
		}

		// check for collisions
		// for the purpose of checking collisions, object 1 is the cue ball
		for (int i = 1; i < objects.size(); i++)
		{
			for (int j = i + 1; j < objects.size(); j++)
			{
				if (objects[i].collidesWith(objects[j]))
				{
					objects[i].calculateCollision(objects[j]);

					cout << "Ball " << i << " is colliding with ball " << j << endl;

					break;
				}
			}
			for (int h = 0; h < pockets.size(); h++)
			{
				if (pocketCollision(pockets[h], objects[i]))
				{
					cout << "Ball " << i << " is colliding with pocket " << h << endl;
				}
			}
			// if the object goes off of the screen
			if (objects[i].transform.loc.x > 1)
			{
				objects[i].transform.loc.x = -1;
			}

			if (objects[i].transform.loc.x < -1)
			{
				objects[i].transform.loc.x = 1;
			}

			if (objects[i].transform.loc.y > 1)
			{
				objects[i].transform.loc.y = -1;
			}

			if (objects[i].transform.loc.y < -1)
			{
				objects[i].transform.loc.y = 1;
			}

			// actually move the object
			objects[i].move(deltaTime);
		}

		//cout << objects[1].transform.loc.x << endl;

		// update the camera

		//camera.update(vec3(), deltaTime);

		for (int i = 0; i < objects.size(); i++)
		{
			// call the current objects draw method
			objects[i].draw();

			// render the game objects
			if (i == 0)
			{
				models[0].render();
			}
			else
			{
				models[1].render();
			}
			glBindVertexArray(0);
			glBindTexture(GL_TEXTURE_2D, texIDs[i]);
			// unbind after drawing
		}

		camera.update(vec3(0, 0, 0), deltaTime);

		glfwSwapBuffers(GLFWwindowPtr);

		// process queued window, mouse/keyboard callback events
		//keyWasDown = keyIsDown;
		glfwPollEvents();

		if (keyIsDown[GLFW_KEY_LEFT])
		{
			//cout << "Left" << endl;
			camera.update(vec3(-40, 0, 0), deltaTime);
		}
		else
		{
			camera.stop();
		}

		if (keyIsDown[GLFW_KEY_RIGHT])
		{
			//cout << "Right" << endl;
			camera.update(vec3(40, 0, 0), deltaTime);
		}
		else
		{
			camera.stop();
		}

		if (keyIsDown[GLFW_KEY_UP])
		{
			//cout << "Up" << endl;
			camera.update(vec3(0, 40, 0), deltaTime);
		}
		else
		{
			camera.stop();
		}

		if (keyIsDown[GLFW_KEY_DOWN])
		{
			//cout << "Down" << endl;
			camera.update(vec3(0, -40, 0), deltaTime);
		}
		else
		{
			camera.stop();
		}

		// check to see if escape key is pressed
		if (keyIsDown[GLFW_KEY_ESCAPE])
		{
			glfwSetWindowShouldClose(GLFWwindowPtr, GL_TRUE);
		}

	}

	for (int i = 0; i < texIDs.size(); i++)
	{
		glDeleteTextures(1, &texIDs[i]);
	}

	glfwTerminate();

	return true;
}
Пример #28
0
	bool FreeImage::onLoad() {

		switch ( this -> loadingType ) {
			case LoadingType::EMPTY:
				{
					this -> freeImage = FreeImage_Allocate( this -> size.x, this -> size.y, this -> BPP, 0, 0, 0 );
					break;
				}
			case LoadingType::FILE: 
				{
					// Check the file signature and deduce its format.
					#ifdef WIN32
					FREE_IMAGE_FORMAT imageFormat = FreeImage_GetFileTypeU( fileNameW.toCString(), 0 );
					#else
					FREE_IMAGE_FORMAT imageFormat = FreeImage_GetFileType( fileName.toCString(), 0 );
					#endif

					// If still unknown, try to guess the file format from the file extension.  
					if ( imageFormat == FIF_UNKNOWN ) {
						#ifdef WIN32
						imageFormat = FreeImage_GetFIFFromFilenameU( fileNameW.toCString() );
						#else
						imageFormat = FreeImage_GetFIFFromFilename( fileName.toCString() );
						#endif
					}

					// If still unknown, return failure.  
					if ( imageFormat == FIF_UNKNOWN ) {
						error( String( "Free Image was unable to detect the file format : " ) << fileName );
						return false;
					}

					// Check that the plugin has reading capabilities and load the file.  
					if ( FreeImage_FIFSupportsReading( imageFormat ) ) {
						#ifdef WIN32
						this -> freeImage = FreeImage_LoadU( imageFormat, fileNameW.toCString() );
						#else
						this -> freeImage = FreeImage_Load( imageFormat, fileName.toCString() );
						#endif
					}

					if ( this -> freeImage == NULL ) {
						error( String( "Free Image was unable to load the picture : " ) << fileName );
						return false;
					}
					if ( this -> size.x == 0 || this -> size.y == 0 ) {
						this -> size.x = FreeImage_GetWidth( this -> freeImage );
						this -> size.y = FreeImage_GetHeight( this -> freeImage );
					}


					if ( this -> loadingFormat == Format::UNDEFINED ) {
						switch ( FreeImage_GetColorType( this -> freeImage ) ) {
							case FIC_PALETTE:
								_updateFormat( Format::R );
								break;
							case FIC_RGB:
								_updateFormat( Format::RGB );
								break;
							default:
								_updateFormat( Format::RGBA );
								break;
						}
					}

					log( this -> fileName << this -> size << " has been loaded successfully !" );
					break;
				}

		}


		//if we have to flip vertically.
		if ( this -> invertY )
			FreeImage_FlipVertical( this -> freeImage );
		//Change BPP
		if ( this -> BPP != FreeImage_GetBPP( this -> freeImage ) )
			_updateBPP();
		//resize
		if ( this -> size != Math::Vec2<Size>( FreeImage_GetWidth( this -> freeImage ), FreeImage_GetHeight( this -> freeImage ) ) )
			_updateSize();

		this -> stride = FreeImage_GetPitch( this -> freeImage );
		return true;
	}
Пример #29
0
void Image::_load(string sFilename)
{
	errlog << "Load " << sFilename << endl;
	//image format
	FREE_IMAGE_FORMAT fif = FIF_UNKNOWN;
	//pointer to the image, once loaded
	FIBITMAP *dib(0);
	//pointer to the image data
	BYTE* bits(0);
	//image width and height
	unsigned int width(0), height(0);
	
	//check the file signature and deduce its format
	fif = FreeImage_GetFileType(sFilename.c_str(), 0);
	//if still unknown, try to guess the file format from the file extension
	if(fif == FIF_UNKNOWN) 
		fif = FreeImage_GetFIFFromFilename(sFilename.c_str());
	//if still unkown, return failure
	if(fif == FIF_UNKNOWN)
	{
		errlog << "Unknown image type for file " << sFilename << endl;
		return;
	}
  
	//check that the plugin has reading capabilities and load the file
	if(FreeImage_FIFSupportsReading(fif))
		dib = FreeImage_Load(fif, sFilename.c_str());
	else
		errlog << "File " << sFilename << " doesn't support reading." << endl;
	//if the image failed to load, return failure
	if(!dib)
	{
		errlog << "Error loading image " << sFilename.c_str() << endl;
		return;
	}  
	//retrieve the image data
  
	//get the image width and height
	width = FreeImage_GetWidth(dib);
	height = FreeImage_GetHeight(dib);
  
	int w = power_of_two(width);
	int h = power_of_two(height);
	int mode, modeflip;
	if(FreeImage_GetBPP(dib) == 24) // RGB 24bit
	{
		mode = GL_RGB;
		modeflip = GL_BGR;
	}
	else if(FreeImage_GetBPP(dib) == 32)  // RGBA 32bit
	{
		mode = GL_RGBA;
		modeflip = GL_BGRA;
	}
	FIBITMAP *bitmap2 = FreeImage_Allocate(w, h, FreeImage_GetBPP(dib));
	FreeImage_Paste(bitmap2, dib, 0, 0, 255);
	FreeImage_FlipVertical(bitmap2);  //Apparently, FreeImage handles this strangely. Flipping beforehand doesn't work right.
	FreeImage_Unload(dib);
  
	bits = FreeImage_GetBits(bitmap2);	//if this somehow one of these failed (they shouldn't), return failure
	if((bits == 0) || (width == 0) || (height == 0))
	{
		errlog << "Something went terribly horribly wrong with getting image bits; just sit and wait for the singularity" << endl;
		return;
	}
  
	//generate an OpenGL texture ID for this texture
	m_iWidth = width;
	m_iHeight = height;
	m_iRealWidth = w;
	m_iRealHeight = h;
	glGenTextures(1, &m_hTex);
	//bind to the new texture ID
	glBindTexture(GL_TEXTURE_2D, m_hTex);
	//store the texture data for OpenGL use
	glTexImage2D(GL_TEXTURE_2D, 0, mode, w, h, 0, modeflip, GL_UNSIGNED_BYTE, bits);
  
	//Free FreeImage's copy of the data
	FreeImage_Unload(bitmap2);
}
Пример #30
0
template<class Tsrc> FIBITMAP* 
CONVERT_TO_BYTE<Tsrc>::convert(FIBITMAP *src, BOOL scale_linear) {
	FIBITMAP *dst = NULL;
	unsigned x, y;

	unsigned width	= FreeImage_GetWidth(src);
	unsigned height = FreeImage_GetHeight(src);

	// allocate a 8-bit dib

	dst = FreeImage_AllocateT(FIT_BITMAP, width, height, 8, 0, 0, 0);
	if(!dst) return NULL;

	// build a greyscale palette
	RGBQUAD *pal = FreeImage_GetPalette(dst);
	for(int i = 0; i < 256; i++) {
		pal[i].rgbRed = (BYTE)i;
		pal[i].rgbGreen = (BYTE)i;
		pal[i].rgbBlue = (BYTE)i;
	}

	// convert the src image to dst
	// (FIBITMAP are stored upside down)
	if(scale_linear) {
		Tsrc max, min;
		double scale;

		// find the min and max value of the image
		Tsrc l_min, l_max;
		min = 255, max = 0;
		for(y = 0; y < height; y++) {
			Tsrc *bits = reinterpret_cast<Tsrc*>(FreeImage_GetScanLine(src, y));
			MAXMIN(bits, width, l_max, l_min);
			if(l_max > max) max = l_max;
			if(l_min < min) min = l_min;
		}
		if(max == min) {
			max = 255; min = 0;
		}

		// compute the scaling factor
		scale = 255 / (double)(max - min);

		// scale to 8-bit
		for(y = 0; y < height; y++) {
			Tsrc *src_bits = reinterpret_cast<Tsrc*>(FreeImage_GetScanLine(src, y));
			BYTE *dst_bits = FreeImage_GetScanLine(dst, y);
			for(x = 0; x < width; x++) {
				dst_bits[x] = (BYTE)( scale * (src_bits[x] - min) + 0.5);
			}
		}
	} else {
		for(y = 0; y < height; y++) {
			Tsrc *src_bits = reinterpret_cast<Tsrc*>(FreeImage_GetScanLine(src, y));
			BYTE *dst_bits = FreeImage_GetScanLine(dst, y);
			for(x = 0; x < width; x++) {
				// rounding
				int q = int(src_bits[x] + 0.5);
				dst_bits[x] = (BYTE) MIN(255, MAX(0, q));
			}
		}
	}

	return dst;
}