コード例 #1
0
/*!
	quake2
*/
IImage* CImageLoaderWAL::loadImage(irr::io::IReadFile* file) const
{
	miptex_quake2 header;

	file->seek(0);
	file->read(&header, sizeof(header));

#ifdef __BIG_ENDIAN__
	header.width = os::Byteswap::byteswap(header.width);
	header.height = os::Byteswap::byteswap(header.height);
#endif

	u32 rawtexsize = header.width * header.height;

	u8 *rawtex = new u8 [ rawtexsize ];

	file->seek ( header.mipmap[0] );
	file->read(rawtex, rawtexsize);

	IImage* image = new CImage(ECF_A8R8G8B8, core::dimension2d<u32>(header.width, header.height));

	CColorConverter::convert8BitTo32Bit(rawtex, (u8*)image->lock(), header.width, header.height, (u8*) colormap_pcx, 0, false);
	image->unlock();

	delete [] rawtex;

	return image;
}
コード例 #2
0
//! creates a surface from the file
IImage* CImageLoaderDDS::loadImage(io::IReadFile* file) const
{
	u8 *memFile = new u8 [ file->getSize() ];
	file->read ( memFile, file->getSize() );

	ddsBuffer *header = (ddsBuffer*) memFile;
	IImage* image = 0;
	s32 width, height;
	eDDSPixelFormat pixelFormat;

	if ( 0 == DDSGetInfo( header, &width, &height, &pixelFormat) )
	{
		image = new CImage(ECF_A8R8G8B8, core::dimension2d<u32>(width, height));

		if ( DDSDecompress( header, (u8*) image->lock() ) == -1)
		{
			image->unlock();
			image->drop();
			image = 0;
		}
	}

	delete [] memFile;
	if ( image )
		image->unlock();

	return image;
}
コード例 #3
0
/*!
	Quake1, Quake2, Hallife lmp texture
*/
IImage* CImageLoaderLMP::loadImage(irr::io::IReadFile* file) const
{
	SLMPHeader header;

	file->seek(0);
	file->read(&header, sizeof(header));

	// maybe palette file
	u32 rawtexsize = header.width * header.height;
	if ( rawtexsize + sizeof ( header ) != file->getSize() )
		return 0;

	u8 *rawtex = new u8 [ rawtexsize ];

	file->read(rawtex, rawtexsize);

	IImage* image = new CImage(ECF_A8R8G8B8, core::dimension2d<u32>(header.width, header.height));

	CColorConverter::convert8BitTo32Bit(rawtex, (u8*)image->lock(), header.width, header.height, (u8*) colormap_h, 0, false);
	image->unlock();

	delete [] rawtex;

	return image;
}
コード例 #4
0
ファイル: CNullDriver.cpp プロジェクト: ChangerR/dream
//! Creates a software image from part of a texture.
IImage* CNullDriver::createImage(ITexture* texture, const position2d<s32>& pos, const dimension2d<u32>& size)
{
	if ((pos==position2di(0,0)) && (size == texture->getSize()))
	{
		IImage* image = new CImage(texture->getColorFormat(), size, texture->lock(ETLM_READ_ONLY), false);
		texture->unlock();
		return image;
	}
	else
	{
		// make sure to avoid buffer overruns
		// make the vector a separate variable for g++ 3.x
		const vector2d<u32> leftUpper(clamp(static_cast<u32>(pos.X), 0u, texture->getSize().Width),
					clamp(static_cast<u32>(pos.Y), 0u, texture->getSize().Height));
		const rectangle<u32> clamped(leftUpper,
					dimension2du(clamp(static_cast<u32>(size.Width), 0u, texture->getSize().Width),
					clamp(static_cast<u32>(size.Height), 0u, texture->getSize().Height)));
		if (!clamped.isValid())
			return 0;
		u8* src = static_cast<u8*>(texture->lock(ETLM_READ_ONLY));
		if (!src)
			return 0;
		IImage* image = new CImage(texture->getColorFormat(), clamped.getSize());
		u8* dst = static_cast<u8*>(image->lock());
		src += clamped.UpperLeftCorner.Y * texture->getPitch() + image->getBytesPerPixel() * clamped.UpperLeftCorner.X;
		for (u32 i=0; i<clamped.getHeight(); ++i)
		{
			CColorConverter::convert_viaFormat(src, texture->getColorFormat(), clamped.getWidth(), dst, image->getColorFormat());
			src += texture->getPitch();
			dst += image->getPitch();
		}
		image->unlock();
		texture->unlock();
		return image;
	}
}
コード例 #5
0
//! creates a surface from the file
IImage* CImageLoaderJPG::loadImage(io::IReadFile* file) const
{
	#ifndef _IRR_COMPILE_WITH_LIBJPEG_
	os::Printer::log("Can't load as not compiled with _IRR_COMPILE_WITH_LIBJPEG_:", file->getFileName(), ELL_DEBUG);
	return 0;
	#else

	if (!file)
		return 0;

	Filename = file->getFileName();

	u8 **rowPtr=0;
	u8* input = new u8[file->getSize()];
	file->read(input, file->getSize());

	// allocate and initialize JPEG decompression object
	struct jpeg_decompress_struct cinfo;
	struct irr_jpeg_error_mgr jerr;

	//We have to set up the error handler first, in case the initialization
	//step fails.  (Unlikely, but it could happen if you are out of memory.)
	//This routine fills in the contents of struct jerr, and returns jerr's
	//address which we place into the link field in cinfo.

	cinfo.err = jpeg_std_error(&jerr.pub);
	cinfo.err->error_exit = error_exit;
	cinfo.err->output_message = output_message;

	// compatibility fudge:
	// we need to use setjmp/longjmp for error handling as gcc-linux
	// crashes when throwing within external c code
	if (setjmp(jerr.setjmp_buffer))
	{
		// If we get here, the JPEG code has signaled an error.
		// We need to clean up the JPEG object and return.

		jpeg_destroy_decompress(&cinfo);

		delete [] input;
		// if the row pointer was created, we delete it.
		if (rowPtr)
			delete [] rowPtr;

		// return null pointer
		return 0;
	}

	// Now we can initialize the JPEG decompression object.
	jpeg_create_decompress(&cinfo);

	// specify data source
	jpeg_source_mgr jsrc;

	// Set up data pointer
	jsrc.bytes_in_buffer = file->getSize();
	jsrc.next_input_byte = (JOCTET*)input;
	cinfo.src = &jsrc;

	jsrc.init_source = init_source;
	jsrc.fill_input_buffer = fill_input_buffer;
	jsrc.skip_input_data = skip_input_data;
	jsrc.resync_to_restart = jpeg_resync_to_restart;
	jsrc.term_source = term_source;

	// Decodes JPG input from whatever source
	// Does everything AFTER jpeg_create_decompress
	// and BEFORE jpeg_destroy_decompress
	// Caller is responsible for arranging these + setting up cinfo

	// read file parameters with jpeg_read_header()
	jpeg_read_header(&cinfo, TRUE);

	bool useCMYK=false;
	if (cinfo.jpeg_color_space==JCS_CMYK)
	{
		cinfo.out_color_space=JCS_CMYK;
		cinfo.out_color_components=4;
		useCMYK=true;
	}
	else
	{
		cinfo.out_color_space=JCS_RGB;
		cinfo.out_color_components=3;
	}
	cinfo.output_gamma=2.2;
	cinfo.do_fancy_upsampling=FALSE;

	// Start decompressor
	jpeg_start_decompress(&cinfo);

	// Get image data
	u16 rowspan = cinfo.image_width * cinfo.out_color_components;
	u32 width = cinfo.image_width;
	u32 height = cinfo.image_height;

	// Allocate memory for buffer
	u8* output = new u8[rowspan * height];

	// Here we use the library's state variable cinfo.output_scanline as the
	// loop counter, so that we don't have to keep track ourselves.
	// Create array of row pointers for lib
	rowPtr = new u8* [height];

	for( u32 i = 0; i < height; i++ )
		rowPtr[i] = &output[ i * rowspan ];

	u32 rowsRead = 0;

	while( cinfo.output_scanline < cinfo.output_height )
		rowsRead += jpeg_read_scanlines( &cinfo, &rowPtr[rowsRead], cinfo.output_height - rowsRead );

	delete [] rowPtr;
	// Finish decompression

	jpeg_finish_decompress(&cinfo);

	// Release JPEG decompression object
	// This is an important step since it will release a good deal of memory.
	jpeg_destroy_decompress(&cinfo);

	// convert image
	IImage* image = 0;
	if (useCMYK)
	{
		image = new CImage(ECF_R8G8B8,
				core::dimension2d<u32>(width, height));
		const u32 size = 3*width*height;
		u8* data = (u8*)image->lock();
		if (data)
		{
			for (u32 i=0,j=0; i<size; i+=3, j+=4)
			{
				// Also works without K, but has more contrast with K multiplied in
//				data[i+0] = output[j+2];
//				data[i+1] = output[j+1];
//				data[i+2] = output[j+0];
				data[i+0] = (char)(output[j+2]*(output[j+3]/255.f));
				data[i+1] = (char)(output[j+1]*(output[j+3]/255.f));
				data[i+2] = (char)(output[j+0]*(output[j+3]/255.f));
			}
		}
		image->unlock();
		delete [] output;
	}
	else
		image = new CImage(ECF_R8G8B8,
				core::dimension2d<u32>(width, height), output);

	delete [] input;

	return image;

	#endif
}
コード例 #6
0
ファイル: CImageLoaderPPM.cpp プロジェクト: Lumirion/pseuwow
//! creates a surface from the file
IImage* CImageLoaderPPM::loadImage(io::IReadFile* file) const
{
	IImage* image;

	if (file->getSize() < 12)
		return 0;

	c8 id[2];
	file->read(&id, 2);

	if (id[0]!='P' || id[1]<'1' || id[1]>'6')
		return 0;

	const u8 format = id[1] - '0';
	const bool binary = format>3;

	core::stringc token;
	getNextToken(file, token);
	const u32 width = core::strtol10(token.c_str());

	getNextToken(file, token);
	const u32 height = core::strtol10(token.c_str());

	u8* data = 0;
	const u32 size = width*height;
	if (format==1 || format==4)
	{
		skipToNextToken(file); // go to start of data

		const u32 bytesize = size/8+(size & 3)?1:0;
		if (binary)
		{
			if (file->getSize()-file->getPos() < (long)bytesize)
				return 0;
			data = new u8[bytesize];
			file->read(data, bytesize);
		}
		else
		{
			if (file->getSize()-file->getPos() < (long)(2*size)) // optimistic test
				return 0;
			data = new u8[bytesize];
			memset(data, 0, bytesize);
			u32 shift=0;
			for (u32 i=0; i<size; ++i)
			{
				getNextToken(file, token);
				if (token == "1")
					data[i/8] |= (0x01 << shift);
				if (++shift == 8)
					shift=0;
			}
		}
		image = new CImage(ECF_A1R5G5B5, core::dimension2d<u32>(width, height));
		if (image)
			CColorConverter::convert1BitTo16Bit(data, (s16*)image->lock(), width, height);
	}
	else
	{
		getNextToken(file, token);
		const u32 maxDepth = core::strtol10(token.c_str());
		if (maxDepth > 255) // no double bytes yet
			return 0;

		skipToNextToken(file); // go to start of data

		if (format==2 || format==5)
		{
			if (binary)
			{
				if (file->getSize()-file->getPos() < (long)size)
					return 0;
				data = new u8[size];
				file->read(data, size);
				image = new CImage(ECF_A8R8G8B8, core::dimension2d<u32>(width, height));
				if (image)
				{
					u8* ptr = (u8*)image->lock();
					for (u32 i=0; i<size; ++i)
					{
						*ptr++ = data[i];
						*ptr++ = data[i];
						*ptr++ = data[i];
						*ptr++ = 255;
					}
				}
			}
			else
			{
				if (file->getSize()-file->getPos() < (long)(2*size)) // optimistic test
					return 0;
				image = new CImage(ECF_A8R8G8B8, core::dimension2d<u32>(width, height));
				if (image)
				{
					u8* ptr = (u8*)image->lock();
					for (u32 i=0; i<size; ++i)
					{
						getNextToken(file, token);
						const u8 num = (u8)core::strtol10(token.c_str());
						*ptr++ = num;
						*ptr++ = num;
						*ptr++ = num;
						*ptr++ = 255;
					}
				}
			}
		}
		else
		{
			const u32 bytesize = 3*size;
			if (binary)
			{
				if (file->getSize()-file->getPos() < (long)bytesize)
					return 0;
				data = new u8[bytesize];
				file->read(data, bytesize);
				image = new CImage(ECF_A8R8G8B8, core::dimension2d<u32>(width, height));
				if (image)
				{
					u8* ptr = (u8*)image->lock();
					for (u32 i=0; i<size; ++i)
					{
						*ptr++ = data[3*i];
						*ptr++ = data[3*i+1];
						*ptr++ = data[3*i+2];
						*ptr++ = 255;
					}
				}
			}
			else
			{
				if (file->getSize()-file->getPos() < (long)(2*bytesize)) // optimistic test
					return 0;
				image = new CImage(ECF_A8R8G8B8, core::dimension2d<u32>(width, height));
				if (image)
				{
					u8* ptr = (u8*)image->lock();
					for (u32 i=0; i<size; ++i)
					{
						getNextToken(file, token);
						*ptr++ = (u8)core::strtol10(token.c_str());
						getNextToken(file, token);
						*ptr++ = (u8)core::strtol10(token.c_str());
						getNextToken(file, token);
						*ptr++ = (u8)core::strtol10(token.c_str());
						*ptr++ = 255;
					}
				}
			}
		}
	}

	if (image)
		image->unlock();

	delete [] data;

	return image;
}
コード例 #7
0
		//! copies the the texture into an open gl texture.
		void COpenGLTexture::uploadTexture(bool newTexture, void* mipmapData,
				u32 level)
		{
			// check which image needs to be uploaded
			IImage* image = level ? MipImage : Image;

			IRR_ASSERT(image);

			// get correct opengl color data values
			GLenum oldInternalFormat = InternalFormat;
			GLint filtering;
			InternalFormat = getOpenGLFormatAndParametersFromColorFormat(
					ColorFormat, filtering, PixelFormat, PixelType);
			// make sure we don't change the internal format of existing images
			if (!newTexture)
				InternalFormat = oldInternalFormat;

			static_cast<COpenGLDriver *>(Driver)->setActiveTexture(0, this);

			IRR_ASSERT(!Driver->haveError());

			// mipmap handling for main texture
			if (!level && newTexture)
			{
#ifndef DISABLE_MIPMAPPING
#ifdef GL_SGIS_generate_mipmap
				// auto generate if possible and no mipmap data is given
				if (HasMipMaps && !mipmapData
				//FIXME
				//&& Driver->queryFeature(EVDF_MIP_MAP_AUTO_UPDATE)
						)
				{

//					if (Driver->getTextureCreationFlag(
//							ETCF_OPTIMIZED_FOR_SPEED))
//						glHint(GL_GENERATE_MIPMAP_HINT_SGIS, GL_FASTEST);
//					else if (Driver->getTextureCreationFlag(
//							ETCF_OPTIMIZED_FOR_QUALITY))
//						glHint(GL_GENERATE_MIPMAP_HINT_SGIS, GL_NICEST);
//					else
					glHint(GL_GENERATE_MIPMAP_HINT_SGIS, GL_DONT_CARE);
					// automatically generate and update mipmaps
					glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);

					//FIXME
//					AutomaticMipmapUpdate=true;
				}
				else
#endif

				{
					// Either generate manually due to missing capability
					// or use predefined mipmap data
//					AutomaticMipmapUpdate = false;
//					regenerateMipMapLevels(mipmapData);
				}
				//FIXME: refactor it
				if (false)
//				if (HasMipMaps) // might have changed in regenerateMipMapLevels
				{
					// enable bilinear mipmap filter
					glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
							GL_LINEAR_MIPMAP_NEAREST);
					glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
							GL_LINEAR);
				}
				else
#else
				//Did not create OpenGL texture mip maps.
				HasMipMaps=false;
#endif
				{
					// enable bilinear filter without mipmaps
					glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
							GL_LINEAR);
					glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
							GL_LINEAR);
				}
			}

			// now get image data and upload to GPU
			void* source = image->lock();
			if (newTexture)
			{
				glTexImage2D(GL_TEXTURE_2D, level, InternalFormat,
						image->getDimension().Width,
						image->getDimension().Height, 0, PixelFormat, PixelType,
						source);
			}
			else
			{
				glTexSubImage2D(GL_TEXTURE_2D, level, 0, 0,
						image->getDimension().Width,
						image->getDimension().Height, PixelFormat, PixelType,
						source);
			}
			image->unlock();

			IRR_ASSERT(!Driver->haveError());
		}
コード例 #8
0
ファイル: CImageLoaderTGA.cpp プロジェクト: Badcreature/sagcg
//! creates a surface from the file
IImage* CImageLoaderTGA::loadImage(io::IReadFile* file) const
{
	STGAHeader header;
	u32 *palette = 0;

	file->read(&header, sizeof(STGAHeader));

#ifdef __BIG_ENDIAN__
	header.ColorMapLength = os::Byteswap::byteswap(header.ColorMapLength);
	header.ImageWidth = os::Byteswap::byteswap(header.ImageWidth);
	header.ImageHeight = os::Byteswap::byteswap(header.ImageHeight);
#endif

	// skip image identification field
	if (header.IdLength)
		file->seek(header.IdLength, true);

	if (header.ColorMapType)
	{
		// create 32 bit palette
		palette = new u32[ header.ColorMapLength];

		// read color map
		u8 * colorMap = new u8[header.ColorMapEntrySize/8 * header.ColorMapLength];
		file->read(colorMap,header.ColorMapEntrySize/8 * header.ColorMapLength);

		// convert to 32-bit palette
		switch ( header.ColorMapEntrySize )
		{
			case 16:
				CColorConverter::convert_A1R5G5B5toA8R8G8B8(colorMap, header.ColorMapLength, palette);
				break;
			case 24:
				CColorConverter::convert_B8G8R8toA8R8G8B8(colorMap, header.ColorMapLength, palette);
				break;
			case 32:
				CColorConverter::convert_B8G8R8A8toA8R8G8B8(colorMap, header.ColorMapLength, palette);
				break;
		}
		delete [] colorMap;
	}

	// read image

	u8* data = 0;

	if (	header.ImageType == 1 || // Uncompressed, color-mapped images.
			header.ImageType == 2 || // Uncompressed, RGB images
			header.ImageType == 3 // Uncompressed, black and white images
		)
	{
		const s32 imageSize = header.ImageHeight * header.ImageWidth * header.PixelDepth/8;
		data = new u8[imageSize];
	  	file->read(data, imageSize);
	}
	else
	if(header.ImageType == 10)
	{
		// Runlength encoded RGB images
		data = loadCompressedImage(file, header);
	}
	else
	{
		os::Printer::log("Unsupported TGA file type", file->getFileName(), ELL_ERROR);
		delete [] palette;
		return 0;
	}

	IImage* image = 0;

	switch(header.PixelDepth)
	{
	case 8:
		image = new CImage(ECF_A1R5G5B5,
			core::dimension2d<u32>(header.ImageWidth, header.ImageHeight));
		if (image)
			CColorConverter::convert8BitTo16Bit((u8*)data,
				(s16*)image->lock(),
				header.ImageWidth,header.ImageHeight,
				header.ImageType == 3 ? 0 : (s32*) palette,
				0,
				(header.ImageDescriptor&0x20)==0);
		break;
	case 16:
		image = new CImage(ECF_A1R5G5B5,
			core::dimension2d<u32>(header.ImageWidth, header.ImageHeight));
		if (image)
			CColorConverter::convert16BitTo16Bit((s16*)data,
				(s16*)image->lock(), header.ImageWidth,	header.ImageHeight, 0, (header.ImageDescriptor&0x20)==0);
		break;
	case 24:
			image = new CImage(ECF_R8G8B8,
				core::dimension2d<u32>(header.ImageWidth, header.ImageHeight));
			if (image)
				CColorConverter::convert24BitTo24Bit(
					(u8*)data, (u8*)image->lock(), header.ImageWidth, header.ImageHeight, 0, (header.ImageDescriptor&0x20)==0, true);
		break;
	case 32:
			image = new CImage(ECF_A8R8G8B8,
				core::dimension2d<u32>(header.ImageWidth, header.ImageHeight));
			if (image)
				CColorConverter::convert32BitTo32Bit((s32*)data,
					(s32*)image->lock(), header.ImageWidth, header.ImageHeight, 0, (header.ImageDescriptor&0x20)==0);
		break;
	default:
		os::Printer::log("Unsupported TGA format", file->getFileName(), ELL_ERROR);
		break;
	}
	if (image)
		image->unlock();

	delete [] data;
	delete [] palette;

	return image;
}
コード例 #9
0
//! creates a surface from the file
IImage* CImageLoaderTGA::loadImage(irr::io::IReadFile* file)
{
    STGAHeader header;
    u8* colorMap = 0;

    file->read(&header, sizeof(STGAHeader));

#ifdef __BIG_ENDIAN__
    header.ColorMapLength = os::Byteswap::byteswap(header.ColorMapLength);
    header.ImageWidth = os::Byteswap::byteswap(header.ImageWidth);
    header.ImageHeight = os::Byteswap::byteswap(header.ImageHeight);
#endif

    // skip image identification field
    if (header.IdLength)
        file->seek(header.IdLength, true);

    if (header.ColorMapType)
    {
        // read color map
        colorMap = new u8[header.ColorMapEntrySize/8 * header.ColorMapLength];
        file->read(colorMap,header.ColorMapEntrySize/8 * header.ColorMapLength);
    }

    // read image

    u8* data = 0;

    if (header.ImageType == 2)
    {
        const s32 imageSize = header.ImageHeight * header.ImageWidth * header.PixelDepth/8;
        data = new u8[imageSize];
        file->read(data, imageSize);
    }
    else if(header.ImageType == 10)
        data = loadCompressedImage(file, header);
    else
    {
        os::Printer::log("Unsupported TGA file type", file->getFileName(), ELL_ERROR);
        if (colorMap)
            delete [] colorMap;
        return 0;
    }

    IImage* image = 0;

    switch(header.PixelDepth)
    {
    case 16:
    {
        image = new CImage(ECF_A1R5G5B5,
                           core::dimension2d<s32>(header.ImageWidth, header.ImageHeight));
        if (image)
            CColorConverter::convert16BitTo16Bit((s16*)data,
                                                 (s16*)image->lock(), header.ImageWidth,	header.ImageHeight, 0, (header.ImageDescriptor&0x20)==0);
    }
    break;
    case 24:
    {
        image = new CImage(ECF_R8G8B8,
                           core::dimension2d<s32>(header.ImageWidth, header.ImageHeight));
        if (image)
            CColorConverter::convert24BitTo24Bit(
                (u8*)data, (u8*)image->lock(), header.ImageWidth, header.ImageHeight, 0, (header.ImageDescriptor&0x20)==0, true);
    }
    break;
    case 32:
    {
        image = new CImage(ECF_A8R8G8B8,
                           core::dimension2d<s32>(header.ImageWidth, header.ImageHeight));
        if (image)
            CColorConverter::convert32BitTo32Bit((s32*)data,
                                                 (s32*)image->lock(), header.ImageWidth, header.ImageHeight, 0, (header.ImageDescriptor&0x20)==0);
    }
    break;
    default:
        os::Printer::log("Unsupported TGA format", file->getFileName(), ELL_ERROR);
        break;
    }
    if (image)
        image->unlock();
    delete [] data;
    if (colorMap)
        delete [] colorMap;

    return image;
}
コード例 #10
0
IImage* CImageLoaderWAL::loadImage(irr::io::IReadFile* file) const
{
	// Try to get the color palette from elsewhere (usually in a pak along with the WAL).
	// If this fails we use the DefaultPaletteQ2.
	static s32 * palette = 0;
#if TRY_LOADING_PALETTE_FROM_FILE
	s32 loadedPalette[256];
#endif
	if (!palette)
	{
#if TRY_LOADING_PALETTE_FROM_FILE
		IImage * paletteImage;
		// Look in a couple different places...
		paletteImage = createImageFromFile("pics/colormap.pcx");
		if (!paletteImage)
			paletteImage = createImageFromFile("pics/colormap.tga");
		if (!paletteImage)
			paletteImage = createImageFromFile("colormap.pcx");
		if (!paletteImage)
			paletteImage = createImageFromFile("colormap.tga");
		if (paletteImage && (paletteImage->getDimension().Width == 256) ) {
			palette = &loadedPalette;
			for (u32 i = 0; i < 256; ++i) {
				palette[i] = paletteImage->getPixel(i, 0).color;
			}
		} else {
			//FIXME: try reading a simple palette from "wal.pal"
			palette = DefaultPaletteQ2;
		}
		if (paletteImage)
			paletteImage->drop();
#endif
	}
	else
	{
		palette = DefaultPaletteQ2;
	}

	SWALHeader header;

	file->seek(0);
	if (file->read(&header, sizeof(SWALHeader)) != sizeof(SWALHeader) )
		return 0;

	if (file->getSize() < header.MipmapOffset[0])
		return 0;
	file->seek(header.MipmapOffset[0]);

	// read image

	const u32 imageSize = header.ImageHeight * header.ImageWidth;
	if (file->getSize() < (long)(imageSize + header.MipmapOffset[0]))
		return 0;

	u8* data = new u8[imageSize];
	file->read(data, imageSize);

	IImage* image = 0;

	image = new CImage(ECF_A1R5G5B5,
		core::dimension2d<u32>(header.ImageWidth, header.ImageHeight));

	// I wrote an 8 to 32 converter, but this works with released Irrlicht code.
	CColorConverter::convert8BitTo16Bit(data,
		(s16*)image->lock(), header.ImageWidth, header.ImageHeight, palette);
	image->unlock();

	delete [] data;

	return image;
}
コード例 #11
0
/*
	Halflite Texture WAD
*/
IImage* CImageLoaderWAL2::loadImage(irr::io::IReadFile* file) const
{
	miptex_halflife header;

	file->seek(0);
	file->read(&header, sizeof(header));

#ifdef __BIG_ENDIAN__
	header.width = os::Byteswap::byteswap(header.width);
	header.height = os::Byteswap::byteswap(header.height);
#endif

	// palette
	//u32 paletteofs = header.mipmap[0] + ((rawtexsize * 85) >> 6) + 2;
	u32 *pal = new u32 [ 192 + 256 ];
	u8 *s = (u8*) pal;

	file->seek ( file->getSize() - 768 - 2 );
	file->read ( s, 768 );
	u32 i;

	for ( i = 0; i < 256; ++i, s+= 3 )
	{
		pal [ 192 + i ] = 0xFF000000 | s[0] << 16 | s[1] << 8 | s[2];
	}

	ECOLOR_FORMAT format = ECF_R8G8B8;

	// transparency in filename;-) funny. rgb:0x0000FF is colorkey
	if ( file->getFileName().findFirst ( '{' ) >= 0 )
	{
		format = ECF_A8R8G8B8;
		pal [ 192 + 255 ] &= 0x00FFFFFF;
	}

	u32 rawtexsize = header.width * header.height;


	u8 *rawtex = new u8 [ rawtexsize ];

	file->seek ( header.mipmap[0] );
	file->read(rawtex, rawtexsize);

	IImage* image = new CImage(format, core::dimension2d<u32>(header.width, header.height));

	switch ( format )
	{
	case ECF_R8G8B8:
		CColorConverter::convert8BitTo24Bit(rawtex, (u8*)image->lock(), header.width, header.height, (u8*) pal + 768, 0, false);
		break;
	case ECF_A8R8G8B8:
		CColorConverter::convert8BitTo32Bit(rawtex, (u8*)image->lock(), header.width, header.height, (u8*) pal + 768, 0, false);
		break;
	}

	image->unlock();

	delete [] rawtex;
	delete [] pal;

	return image;
}
コード例 #12
0
		//! Returns JPG image
		IImage* SharedImageLoaderJpg::createImage(io::IReadFile* file)
		{
			IRR_ASSERT(file);

			s32 jfif = 0;
			file->seek(6);
			file->read(&jfif, sizeof(s32));

			bool isJpegFile = jfif == 0x4a464946 || jfif == 0x4649464a;

			IRR_ASSERT(isJpegFile);

			file->seek(0);

			u8 **rowPtr = 0;
			u8* input = new u8[file->getSize()];
			file->read(input, file->getSize());

			// allocate and initialize JPEG decompression object
			struct jpeg_decompress_struct cinfo;

			struct SJpgErrorMgr jerr;

			//We have to set up the error handler first, in case the initialization
			//step fails.  (Unlikely, but it could happen if you are out of memory.)
			//This routine fills in the contents of struct jerr, and returns jerr's
			//address which we place into the link field in cinfo.

			cinfo.err = jpeg_std_error(&jerr.pub);

			cinfo.err->error_exit = StaticJpgExtension::errorExit;
			cinfo.err->output_message = StaticJpgExtension::outputMessage;

			// compatibility fudge:
			// we need to use setjmp/longjmp for error handling as gcc-linux
			// crashes when throwing within external c code
			if (setjmp(jerr.setjmp_buffer))
			{
				// If we get here, the JPEG code has signaled an error.
				// We need to clean up the JPEG object and return.

				jpeg_destroy_decompress(&cinfo);

				delete[] input;

				// if the row pointer was created, we delete it.
				if (rowPtr)
				{
					delete[] rowPtr;
				}

				IRR_ASSERT(false);
			}

			// Now we can initialize the JPEG decompression object.
			jpeg_create_decompress(&cinfo);

			// specify data source
			jpeg_source_mgr jsrc;

			// Set up data pointer
			jsrc.bytes_in_buffer = file->getSize();
			jsrc.next_input_byte = (JOCTET*) input;
			cinfo.src = &jsrc;

			jsrc.init_source = StaticJpgExtension::initSource;
			jsrc.fill_input_buffer = StaticJpgExtension::fillInputBuffer;
			jsrc.skip_input_data = StaticJpgExtension::skipInputData;
			jsrc.resync_to_restart = jpeg_resync_to_restart;
			jsrc.term_source = StaticJpgExtension::termSource;

			// Decodes JPG input from whatever source
			// Does everything AFTER jpeg_create_decompress
			// and BEFORE jpeg_destroy_decompress
			// Caller is responsible for arranging these + setting up cinfo

			// read file parameters with jpeg_read_header()
			jpeg_read_header(&cinfo, TRUE);

			bool useCMYK = false;
			if (cinfo.jpeg_color_space == JCS_CMYK)
			{
				cinfo.out_color_space = JCS_CMYK;
				cinfo.out_color_components = 4;
				useCMYK = true;
			}
			else
			{
				cinfo.out_color_space = JCS_RGB;
				cinfo.out_color_components = 3;
			}
			cinfo.do_fancy_upsampling = FALSE;

			// Start decompressor
			jpeg_start_decompress(&cinfo);

			// Get image data
			u16 rowspan = cinfo.image_width * cinfo.out_color_components;
			u32 width = cinfo.image_width;
			u32 height = cinfo.image_height;

			// Allocate memory for buffer
			u8* output = new u8[rowspan * height];

			// Here we use the library's state variable cinfo.output_scanline as the
			// loop counter, so that we don't have to keep track ourselves.
			// Create array of row pointers for lib
			rowPtr = new u8*[height];

			for (u32 i = 0; i < height; i++)
			{
				rowPtr[i] = &output[i * rowspan];
			}

			u32 rowsRead = 0;

			while (cinfo.output_scanline < cinfo.output_height)
			{
				rowsRead += jpeg_read_scanlines(&cinfo, &rowPtr[rowsRead],
						cinfo.output_height - rowsRead);
			}

			delete[] rowPtr;

			// Finish decompression
			jpeg_finish_decompress(&cinfo);

			// Release JPEG decompression object
			// This is an important step since it will release a good deal of memory.
			jpeg_destroy_decompress(&cinfo);

			// convert image
			IImage* result = 0;
			if (useCMYK)
			{
				result = IImage::createEmptyImage(ECF_R8G8B8,
						dimension2du(width, height));

				const u32 size = 3 * width * height;
				u8* data = (u8*) result->lock();
				if (data)
				{
					for (u32 i = 0, j = 0; i < size; i += 3, j += 4)
					{
						// Also works without K, but has more contrast with K multiplied in
						//				data[i+0] = output[j+2];
						//				data[i+1] = output[j+1];
						//				data[i+2] = output[j+0];
						data[i + 0] = (char) (output[j + 2]
								* (output[j + 3] / 255.f));
						data[i + 1] = (char) (output[j + 1]
								* (output[j + 3] / 255.f));
						data[i + 2] = (char) (output[j + 0]
								* (output[j + 3] / 255.f));
					}
				}
				result->unlock();
				delete[] output;
			}
			else
			{
				result = IImage::createRawImage(ECF_R8G8B8,
						dimension2du(width, height), output);
			}

			delete[] input;

			return result;
		}