Texture* SolidColorTextureCache::CreateFor(const Color &color, Texture *existing)
{
	LOG_INFO(LOGCAT_ASSETS, "SolidColorTextureCache: creating texture for color 0x%8x.\n", color.ToInt());

	Image *img = new Image();
	bool imageCreateSuccess = img->Create(8, 8, IMAGE_FORMAT_RGBA);
	ASSERT(imageCreateSuccess == true);

	Texture *texture;
	if (existing != NULL)
	{
		texture = existing;
		texture->Release();
	}
	else
		texture = new Texture();

	img->Clear(color);	
	bool success = texture->Create(m_graphicsDevice, img);
	SAFE_DELETE(img);

	if (!success)
	{
		// if we allocated the texture ourselves, we should free it
		if (existing != NULL)
		{
			SAFE_DELETE(texture);
		}
	}

	return texture;
}
예제 #2
0
Resource* BLPImporter::Import( const String& pFilename, const String& /*pParams*/ )
{
	WoW::BLPFile        blpFile;
	WoW::BLPFileReader  blpFileReader( blpFile );

	blpFileReader.Read( pFilename );

	Image::Format format;
	if( blpFile.mHeader.mCompression == 2 )
	{
		if( blpFile.mHeader.mAlphaBits == 0 )
			format = Image::Format_DXT1;
		else if( blpFile.mHeader.mAlphaBits == 8 )
			format = Image::Format_DXT3;
		else
			format = Image::Format_DXT5;
	}
	else
	{
		format = Image::Format_R8G8B8A8;
	}

	Image img;
	img.Create( blpFile.mHeader.mSizeX, blpFile.mHeader.mSizeY, format, blpFile.mMipmapCount );

	memcpy( img.GetData(), &blpFile.mData[0], blpFile.mData.size() );

	Texture2D* tex2D = Cast<Texture2D>(Texture2D::StaticClass()->AllocateNew( pFilename ));
	tex2D->Create( img );
	
	return tex2D;	
}
예제 #3
0
void GLTexture2D::Upload() {
	
	arx_assert(tex != GL_NONE);
	
	glBindTexture(GL_TEXTURE_2D, tex);
	renderer->GetTextureStage(0)->current = this;
	
	GLint internal;
	GLenum format;
	if(flags & Intensity) {
		internal = GL_INTENSITY8, format = GL_RED;
	} else if(mFormat == Image::Format_L8) {
		internal = GL_LUMINANCE8, format = GL_LUMINANCE;
	} else if(mFormat == Image::Format_A8) {
		internal = GL_ALPHA8, format = GL_ALPHA;
	} else if(mFormat == Image::Format_L8A8) {
		internal = GL_LUMINANCE8_ALPHA8, format = GL_LUMINANCE_ALPHA;
	} else if(mFormat == Image::Format_R8G8B8) {
		internal = GL_RGB8, format = GL_RGB;
	} else if(mFormat == Image::Format_B8G8R8) {
		internal = GL_RGB8, format = GL_BGR;
	} else if(mFormat == Image::Format_R8G8B8A8) {
		internal = GL_RGBA8, format = GL_RGBA;
	} else if(mFormat == Image::Format_B8G8R8A8) {
		internal = GL_RGBA8, format = GL_BGRA;
	} else {
		arx_assert(false, "Unsupported image format: %ld", long(mFormat));
		return;
	}
	
	if(storedSize != size) {
		flags &= ~HasMipmaps;
	}
	
	if(hasMipmaps()) {
		glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
	} else {
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
	}
	
	// TODO handle GL_MAX_TEXTURE_SIZE
	
	if(storedSize != size) {
		Image extended;
		extended.Create(storedSize.x, storedSize.y, mImage.GetFormat());
		extended.extendClampToEdgeBorder(mImage);
		glTexImage2D(GL_TEXTURE_2D, 0, internal, storedSize.x, storedSize.y, 0, format,
		             GL_UNSIGNED_BYTE, extended.GetData());
	} else {
		glTexImage2D(GL_TEXTURE_2D, 0, internal, size.x, size.y, 0, format,
		             GL_UNSIGNED_BYTE, mImage.GetData());
	}
	
	if(renderer->getMaxAnisotropy() >= 1.f) {
		glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, renderer->getMaxAnisotropy());
	}
}
예제 #4
0
Image Texture::CopyToImage() const
{
    // Easy case: empty texture
    if (!myTexture)
        return Image();

    EnsureGlContext();

    // Make sure that the current texture binding will be preserved
    priv::TextureSaver save;

    // Create an array of pixels
    std::vector<Uint8> pixels(myWidth * myHeight * 4);

    if ((myWidth == myTextureWidth) && (myHeight == myTextureHeight) && !myPixelsFlipped)
    {
        // Texture is not padded nor flipped, we can use a direct copy
        GLCheck(glBindTexture(GL_TEXTURE_2D, myTexture));
        GLCheck(glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, &pixels[0]));
    }
    else
    {
        // Texture is either padded or flipped, we have to use a slower algorithm

        // All the pixels will first be copied to a temporary array
        std::vector<Uint8> allPixels(myTextureWidth * myTextureHeight * 4);
        GLCheck(glBindTexture(GL_TEXTURE_2D, myTexture));
        GLCheck(glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, &allPixels[0]));

        // Then we copy the useful pixels from the temporary array to the final one
        const Uint8* src = &allPixels[0];
        Uint8* dst = &pixels[0];
        int srcPitch = myTextureWidth * 4;
        int dstPitch = myWidth * 4;

        // Handle the case where source pixels are flipped vertically
        if (myPixelsFlipped)
        {
            src += srcPitch * (myHeight - 1);
            srcPitch = -srcPitch;
        }

        for (unsigned int i = 0; i < myHeight; ++i)
        {
            std::memcpy(dst, src, dstPitch);
            src += srcPitch;
            dst += dstPitch;
        }
    }

    // Create the image
    Image image;
    image.Create(myWidth, myHeight, &pixels[0]);

    return image;
}
예제 #5
0
bool AVI :: Load(std :: string fname,bool loopflag,Texture *tex)				// Opens An AVI File
{
	// copy over looping flag
	loop=loopflag;

	// do we have a texture manager?
	if(!tex)
		return false;
	// copy it over
	tman=tex;

	hdc=CreateCompatibleDC(0);									// Get a compatible DC
	hdd = DrawDibOpen();										// Grab A Device Context For Our Dib


	AVIFileInit();												// Opens The AVIFile Library

	// Opens The AVI Stream
	if (AVIStreamOpenFromFile(&pavi, fname.c_str(), streamtypeVIDEO, 0, OF_READ, NULL) !=0)
		return false;

	AVIStreamInfo(pavi, &psi, sizeof(psi));						// Reads Information About The Stream Into psi
	width=psi.rcFrame.right-psi.rcFrame.left;					// Width Is Right Side Of Frame Minus Left
	height=psi.rcFrame.bottom-psi.rcFrame.top;					// Height Is Bottom Of Frame Minus Top

	lastframe=AVIStreamLength(pavi);							// The Last Frame Of The Stream

	mpf=AVIStreamSampleToTime(pavi,lastframe)/lastframe;		// Calculate Rough Milliseconds Per Frame

	bmih.biSize = sizeof (BITMAPINFOHEADER);					// Size Of The BitmapInfoHeader
	bmih.biPlanes = 1;											// Bitplanes	
	bmih.biBitCount = 24;										// Bits Format We Want (24 Bit, 3 Bytes)
	bmih.biWidth = 256;											// Width We Want (256 Pixels)
	bmih.biHeight = 256;										// Height We Want (256 Pixels)
	bmih.biCompression = BI_RGB;								// Requested Mode = RGB

	hBitmap = CreateDIBSection (hdc, (BITMAPINFO*)(&bmih), DIB_RGB_COLORS, (void**)(&data), NULL, NULL);
	SelectObject (hdc, hBitmap);								// Select hBitmap Into Our Device Context (hdc)

	pgf=AVIStreamGetFrameOpen(pavi, NULL);						// Create The PGETFRAME	Using Our Request Mode
	if (pgf==NULL)
		return false;

	// create the texture
	Image img;
	img.Create(256,256,false);									// set dimensions of texture
	img.SetImage(data);											// set the texture information
	texid=tman->Create(&img);									// create the texture

	// clear the time position 
	pos=0;

	// success
	return true;
}
예제 #6
0
bool OpenGLRenderer::getSnapshot(Image & image) {
	
	Vec2i size = mainApp->getWindow()->getSize();
	
	image.Create(size.x, size.y, Image::Format_R8G8B8);
	
	glReadPixels(0, 0, size.x, size.y, GL_RGB, GL_UNSIGNED_BYTE, image.GetData()); 
	
	image.FlipY();
	
	return true;
}
예제 #7
0
void CTextureCtrl::SetPalette(DC2_ENTRY_GFX *gfx_entry, u16 *gfx_data, int depth, int cx, int cy)
{
	Image img;

	switch(depth)
	{
	case 0: depth=4; break;		// 4 bpp, get 16 colors
	case 1: depth=8; break;		// 8 bpp, get 256 colors
	case 2:		// 15 bpp, no palette needed here
		texture.w=texture.h=0;
		Invalidate();
		return;
	}

	u16* clut=new u16[1<<depth];
	// create greyscale clut
	if(!gfx_entry && !gfx_data)
	{
		SetGreyscale(depth);
		for(int i=0; i<(1<<depth); i++)
			clut[i]=TIMRGB(palette[i].rgbRed,palette[i].rgbGreen,palette[i].rgbBlue);
	}
	// otherwise copy section
	else
		for(int i=0; i<(1<<depth); i++)
			clut[i]=GetClutColor(gfx_entry,gfx_data,i+cx,cy);

	// determine client size
	CRect rect;
	GetClientRect(&rect);

	// create canvas
	img.Create(rect.Width()/COLOR_CELL*COLOR_CELL,rect.Height(),24,NULL);
	// draw clut to bitmap
	for(int i=0; i<(1<<depth); i++)
	{
		RGBQUAD pixel=ClutToRgb(clut[i],0);

		int x=(i%(rect.Width()/COLOR_CELL))*COLOR_CELL;
		int y=(i/(rect.Width()/COLOR_CELL))*COLOR_CELL;
		// set color
		for(int xi=0; xi<COLOR_CELL; xi++)
			for(int yi=0; yi<COLOR_CELL; yi++)
				img.SetPixelAt(x+xi,y+yi,*((u32*)&pixel));
	}

	texture.LoadBitmap(img);
	Invalidate();

	delete[] clut;
}
예제 #8
0
bool OpenGLRenderer::getSnapshot(Image & image, size_t width, size_t height) {
	
	// TODO handle scaling on the GPU so we don't need to download the whole image

	// duplication to ensure use of Image::Format_R8G8B8
	Image fullsize;
	Vec2i size = mainApp->getWindow()->getSize();
	fullsize.Create(size.x, size.y, Image::Format_R8G8B8);
	glReadPixels(0, 0, size.x, size.y, GL_RGB, GL_UNSIGNED_BYTE, fullsize.GetData()); 

	image.ResizeFrom(fullsize, width, height, true);

	return true;
}
예제 #9
0
bool PackedTexture::InsertImage(const Image & pImg, int & pOffsetU, int & pOffsetV, unsigned int & pTextureIndex) {
	
	// Validate image size
	if(pImg.GetWidth() > mTexSize || pImg.GetHeight() > mTexSize) {
		return false;
	}
	
	// Copy to one of the existing image
	TextureTree::Node * node = NULL;
	unsigned int nodeTree = 0;
	
	for(unsigned int i = 0; i < mTexTrees.size(); i++) {
		node = mTexTrees[i]->InsertImage( pImg );
		nodeTree = i;
	}
	
	// No space found, create a new tree
	if(!node) {
		
		mTexTrees.push_back(new TextureTree(mTexSize));
		
		Image* newPage = new Image();
		newPage->Create(mTexSize, mTexSize, mTexFormat);
		newPage->Clear();
		
		mImages.push_back(newPage);
		
		node = mTexTrees[mTexTrees.size() - 1]->InsertImage(pImg);
		nodeTree = mTexTrees.size() - 1;
	}
	
	// A node must have been found.
	arx_assert(node);
	
	// Copy texture there
	if(node) {
		
		mImages[nodeTree]->Copy( pImg, node->mRect.left, node->mRect.top );
		
		// Copy values back into info structure.
		pOffsetU = node->mRect.left;
		pOffsetV = node->mRect.top;
		pTextureIndex = nodeTree;
	}
	
	return node != NULL;
}
예제 #10
0
bool OpenGLRenderer::getSnapshot(Image & image, size_t width, size_t height) {
	
	// TODO handle scaling on the GPU so we don't need to download the whole image
	
	Image fullsize;
	
	getSnapshot(fullsize);
	
 	image.Create(width, height, Image::Format_R8G8B8);
	
	GLint ret = gluScaleImage(GL_RGB, fullsize.GetWidth(), fullsize.GetHeight(), GL_UNSIGNED_BYTE,
	                          fullsize.GetData(), width, height, GL_UNSIGNED_BYTE, image.GetData());
	
	if(ret) {
		LogWarning << "Failed to scaled down screen capture: " << ret << " = " << gluErrorString(ret);
		return false;
	}
	
	return true;
}
예제 #11
0
Image RenderWindow::Capture() const
{
    Image image;
    if (SetActive())
    {
        int width = static_cast<int>(GetWidth());
        int height = static_cast<int>(GetHeight());

        // copy rows one by one and flip them (OpenGL's origin is bottom while SFML's origin is top)
        std::vector<Uint8> pixels(width * height * 4);
        for (int i = 0; i < height; ++i)
        {
            Uint8* ptr = &pixels[i * width * 4];
            GLCheck(glReadPixels(0, height - i - 1, width, 1, GL_RGBA, GL_UNSIGNED_BYTE, ptr));
        }

        image.Create(width, height, &pixels[0]);
    }

    return image;
}
예제 #12
0
bool TextureContainer::CreateHalo() {
	
	Image srcImage;
	if(!srcImage.LoadFromFile(m_pTexture->getFileName())) {
		return false;
	}
	
	// Allocate and add the texture to the linked list of textures;
	res::path haloName = m_texName.string();
	haloName.append("_halo");
	TextureHalo = new TextureContainer(haloName, NoMipmap | NoColorKey);
	if(!TextureHalo) {
		return false;
	}
	
	TextureHalo->m_pTexture = GRenderer->CreateTexture2D();
	if(!TextureHalo->m_pTexture) {
		return true;
	}
	
	Image im;
	
	int width = m_size.x + HALO_RADIUS * 2;
	int height = m_size.y + HALO_RADIUS * 2;
	im.Create(width, height, srcImage.GetFormat());
	
	// Center the image, offset by radius to contain the edges of the blur
	im.Clear();
	im.Copy(srcImage, HALO_RADIUS, HALO_RADIUS);
	
	// Keep a copy of the image at this stage, in order to apply proper alpha masking later
	Image copy = im;
	
	// Convert image to grayscale, and turn it to black & white
	im.ToGrayscale(Image::Format_L8A8);
	im.ApplyThreshold(0, ~0);

	// Blur the image
	im.Blur(HALO_RADIUS);

	// Increase the gamma of the blur outline
	im.QuakeGamma(10.0f);

	// Set alpha to inverse of original image alpha
	copy.ApplyColorKeyToAlpha();
	im.SetAlpha(copy, true);
	
	TextureHalo->m_pTexture->Init(im, 0);
	
	TextureHalo->m_size.x = TextureHalo->m_pTexture->getSize().x;
	TextureHalo->m_size.y = TextureHalo->m_pTexture->getSize().y;
	
	Vec2i storedSize = TextureHalo->m_pTexture->getStoredSize();
	TextureHalo->uv = Vec2f(
		float(TextureHalo->m_size.x) / storedSize.x,
		float(TextureHalo->m_size.y) / storedSize.y
	);
	TextureHalo->hd = Vec2f(.5f / storedSize.x, .5f / storedSize.y);
	
	return true;
}
예제 #13
0
Resource* DevILImporter::Import( const String& pFilename, const String& /*pParams*/ )
{
    ILuint  imageName;

    // Load the image. DevIL will guess the type of the image file using it's extension and if needed it's header.
    ilGenImages( 1, &imageName );
    ilBindImage( imageName );

    // Load the image.
    if( !ilLoadImage( const_cast<char*>(pFilename.c_str()) ) )
        throw ResourceImportException( ToString(ilGetError()), Here );

    // Get the image params.
    ILint bytesPerPixel   = ilGetInteger( IL_IMAGE_BYTES_PER_PIXEL );
    ILint imgFormat       = ilGetInteger( IL_IMAGE_FORMAT );
    ILint imgWidth        = ilGetInteger( IL_IMAGE_WIDTH );
    ILint imgHeight       = ilGetInteger( IL_IMAGE_HEIGHT );

    // We do not support palettized texture currently, so un-palettize them!
    if( imgFormat == IL_COLOR_INDEX )
    {
        switch( ilGetInteger( IL_PALETTE_TYPE ) )
        {
        case IL_PAL_RGB24:
        case IL_PAL_RGB32:
            imgFormat = IL_RGB;
            break;
        case IL_PAL_BGR24:
        case IL_PAL_BGR32:
            imgFormat = IL_BGR;
            break;
        case IL_PAL_RGBA32:
            imgFormat = IL_RGBA;
            break;
        case IL_PAL_BGRA32:
            imgFormat = IL_BGRA;
            break;
        default:
            debugBreak();
        }

        ilConvertImage( imgFormat, IL_UNSIGNED_BYTE );
        bytesPerPixel = ilGetInteger( IL_IMAGE_BYTES_PER_PIXEL );
        imgFormat     = ilGetInteger( IL_IMAGE_FORMAT );
    }

    // Find what is the gamedesk internal image format that will be used.
    Image::Format gdImgFormat = GetImageFormat( imgFormat, bytesPerPixel );

    Image newImage;
    newImage.Create( imgWidth, imgHeight, gdImgFormat );
    memcpy( newImage.GetData(), ilGetData(), imgWidth*imgHeight*bytesPerPixel );

    Texture* newTexture = NULL;

    // Allocate and create using image.
    if( imgWidth == 1 || imgHeight == 1 )
    {
        Texture1D* tex = Cast<Texture1D>(Texture1D::StaticClass()->AllocateNew( pFilename ));
        tex->Create( newImage );
        newTexture = tex;
    }
    else
    {
        Texture2D* tex = Cast<Texture2D>(Texture2D::StaticClass()->AllocateNew( pFilename ));
        tex->Create( newImage );
        newTexture = tex;
    }

    // The DevIL copy of the image is not needed anymore, so destroy it.
    ilDeleteImages( 1, &imageName );

    return newTexture;
}
예제 #14
0
bool Font::insertGlyph(u32 character) {
	
	FT_Error error;
	FT_UInt glyphIndex = FT_Get_Char_Index(m_FTFace, character);
	if(!glyphIndex) {
		insertPlaceholderGlyph(character);
		return false;
	}
	
	error = FT_Load_Glyph(m_FTFace, glyphIndex, FT_LOAD_FORCE_AUTOHINT);
	if(error) {
		insertPlaceholderGlyph(character);
		return false;
	}
	
	error = FT_Render_Glyph(m_FTFace->glyph, FT_RENDER_MODE_NORMAL);
	if(error) {
		insertPlaceholderGlyph(character);
		return false;
	}
	
	// Fill in info for this glyph.
	Glyph & glyph = m_Glyphs[character];
	glyph.size.x = m_FTFace->glyph->bitmap.width;
	glyph.size.y = m_FTFace->glyph->bitmap.rows;
	glyph.advance.x = m_FTFace->glyph->linearHoriAdvance / 65536.0f;
	glyph.advance.y = m_FTFace->glyph->linearVertAdvance / 65536.0f;
	glyph.lsb_delta = m_FTFace->glyph->lsb_delta;
	glyph.rsb_delta = m_FTFace->glyph->rsb_delta;
	glyph.draw_offset.x = m_FTFace->glyph->bitmap_left;
	glyph.draw_offset.y = m_FTFace->glyph->bitmap_top - m_FTFace->glyph->bitmap.rows;
	glyph.uv_start = Vec2f::ZERO;
	glyph.uv_end = Vec2f::ZERO;
	glyph.texture = 0;
	
	// Some glyphs like spaces have a size of 0...
	if(glyph.size.x != 0 && glyph.size.y != 0) {
		
		Image imgGlyph;
		imgGlyph.Create(glyph.size.x, glyph.size.y, Image::Format_A8);
		
		FT_Bitmap * srcBitmap = &m_FTFace->glyph->bitmap;
		arx_assert(srcBitmap->pitch == srcBitmap->width);
		
		// Copy pixels
		unsigned char * src = srcBitmap->buffer;
		unsigned char * dst = imgGlyph.GetData();
		memcpy(dst, src, glyph.size.x * glyph.size.y);
		
		Vec2i offset;
		m_Textures->insertImage(imgGlyph, glyph.texture, offset);
		
		// Compute UV mapping for each glyph.
		const float textureSize = m_Textures->getTextureSize();
		glyph.uv_start.x = offset.x / textureSize;
		glyph.uv_start.y = offset.y / textureSize;
		glyph.uv_end.x = (offset.x + glyph.size.x) / textureSize;
		glyph.uv_end.y = (offset.y + glyph.size.y) / textureSize;
	}
	
	return true;
}
예제 #15
0
int main(int argc, char *argv[])
{
// For detecting memory leaks
#ifdef _MSVC
    _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
    _CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_DEBUG );
#endif

    //// Seed the random number generator
    //srand( (unsigned int)time( 0 ) );

    // Display license
    std::cout
        << "RayWatch - A simple cross-platform RayTracer."                  << std::endl
        << "Copyright (C) 2008"                                             << std::endl
        << "  Angelo Rohit Joseph Pulikotil,"                               << std::endl
        << "  Francis Xavier Joseph Pulikotil"                              << std::endl
        << "This program comes with ABSOLUTELY NO WARRANTY."                << std::endl
        << "This is free software, and you are welcome to redistribute it"  << std::endl
        << "under certain conditions; see <http://www.gnu.org/licenses/>."  << std::endl << std::endl;

    if( argc < 3 )
    {
        std::cout << "Insufficient arguments" << std::endl << std::endl;
        std::cout << "Syntax (to render a Scene file):" << std::endl << argv[0] << " <input scene filename> <output bitmap filename> [width] [height]" << std::endl << std::endl;
        std::cout << "Syntax (to generate a sample file): " << std::endl << argv[0] << " --gen:<sample name> <output scene filename>" << std::endl << std::endl;
        std::cout << "Currently supported samples are CornellBox, Example1, Example2" << std::endl;
        return -1;
    }

    // If we're supposed to generate a sample file
    if( Utility::String::CaseInsensitiveCompare( std::string( argv[1] ).substr(0, 6), "--gen:" ) == 0 )
    {
        const std::string sampleName = std::string( argv[1] ).substr( 6 );

        bool bResult = false;
        if( Utility::String::CaseInsensitiveCompare( sampleName, "CornellBox" ) == 0 )
        {
            bResult = Examples::CornellBox( argv[2] );
        }
        else if( Utility::String::CaseInsensitiveCompare( sampleName, "Example1" ) == 0 )
        {
            bResult = Examples::Example1( argv[2] );
        }
        else if( Utility::String::CaseInsensitiveCompare( sampleName, "Example2" ) == 0 )
        {
            bResult = Examples::Example2( argv[2] );
        }
        else  // We don't have this sample
            std::cout << "Error: Unknown sample name: " << sampleName << std::endl;

        if( !bResult )
            return -1;

        std::cout << "Sample '" << sampleName << "' written to file: " << argv[2] << std::endl;
        return 0;
    }

    // Get the required width
    int width = 500;
    if( argc > 3 )
    {
        if( !Utility::String::FromString(width, argv[3]) || (width < 1) )
        {
            std::cout << "Error: Invalid integer specified for width: " << argv[3] << std::endl;
            return -1;
        }
    }

    // Get the required height
    int height = 500;
    if( argc > 4 )
    {
        if( !Utility::String::FromString(height, argv[4]) || (height < 1) )
        {
            std::cout << "Error: Invalid integer specified for height: " << argv[4] << std::endl;
            return -1;
        }
    }

    // Create a Camera
    Camera camera;
    camera._position    .Set( 0, 0, 0 );
    camera._hFov        = 45 * (width / (float)height);
    camera._vFov        = 45;

    // Create an Image
    Image image;
    if( !image.Create( width, height ) )
    {
        std::cout << "Error: Failed to create Image of size " << width << "x" << height << std::endl;
        return -1;
    }

    // Open the input scene file
    std::fstream stream;
    stream.open( argv[1], std::ios_base::in );
    if( !stream.is_open() )
    {
        std::cout << "Error: Failed to open input scene file: " << argv[1] << std::endl;
        return -1;
    }

    // Create a Deserializer for the stream
    Deserializer d;
    if( !d.Open( stream ) )
    {
        std::cout << "Error: Failed to read file: " << argv[1] << std::endl;
        return -1;
    }

    // Load the scene from the stream
    Scene *pScene = d.Deserialize<Scene>( 0 );
    if( !pScene )
    {
        std::cout << "Error: Failed to load Scene from file: " << argv[1] << std::endl;
        return -1;
    }

    // Create a RayTracer and ray trace the scene
    RayTracer rayTracer;
    std::cout << "RayTracing";
    const bool bRTResult = rayTracer.Render( camera, *pScene, image );
    std::cout << "Done" << std::endl;

    // We're done with the scene, delete it
    SafeDeleteScalar( pScene );

    if( !bRTResult )
    {
        std::cout << "Error: Failed while RayTracing the Scene." << std::endl;
        return -1;
    }

    // Save the image to the required output file
    if( !image.Save( argv[2] ) )
    {
        std::cout << "Error: Failed while saving image to file: " << argv[2] << std::endl;
        return -1;
    }

    return 0;
}
예제 #16
0
파일: vidrgb.cpp 프로젝트: jeez/iqr
int main(int argc, char **argv)

{
  Atom                atomWMDeleteWindow;
  int	              screenNumber;
  Screen              *screen;
  Window              window;
  XWindowAttributes   windowAttributes;
  Colormap            colormap;
  PaletteInfo         paletteInfo;
  Image               image;
  XImage              *xImage;
  int                 x, y;
  int                 captureFrame;
  XEvent              event;
  bool                sizeChanged;


  // ProgramExit initialization

  display = NULL;
  v4l = -1;
  captureBuf = NULL;

  on_exit(ProgramExit, NULL);

  // Get command line options

  magnification = 1;

  if (argc > 1) {
    magnification = atoi(argv[1]);
  } // end if

  magnification = max(1, magnification);

  printf("Magnification is %i\n", magnification);

  // Open display

  if ((display = XOpenDisplay(NULL)) == NULL) { // NULL for DISPLAY
    printf("Error: XOpenDisplay() failed\n");
    exit(1);
  } // end if

  screenNumber = DefaultScreen(display);

  screen = XScreenOfDisplay(display, screenNumber);

  // Obtain WM protocols atom for ClientMessage exit event

  if ((atomWMDeleteWindow = XInternAtom(display, AtomWMDeleteWindowName, True)) == None) {
    printf("Error: %s atom does not exist\n", AtomWMDeleteWindowName);
    exit(1);
  } // end if

  // Create window, inheriting depth and visual from root window

  window = XCreateSimpleWindow(
    display,
    RootWindowOfScreen(screen),
    0, // x
    0, // y
    640, // width
    480, // height
    0,                          // border width
    BlackPixelOfScreen(screen), // border
    BlackPixelOfScreen(screen)  // background
    );

  XStoreName(display, window, "V4L RGB Test");

  XGetWindowAttributes(display, window, &windowAttributes);

  if (((windowAttributes.depth == 8) && (windowAttributes.visual->c_class != PseudoColor)) ||
      ((windowAttributes.depth > 8) && (windowAttributes.visual->c_class != TrueColor))) {
    printf("Error: Visual not supported\n");
    exit(1);
  } // end if

  // Create PseudoColor HI240 colormap, if needed

  if (windowAttributes.depth == 8) {
    colormap = XCreateColormap(display, window, windowAttributes.visual, AllocAll);
    paletteInfo.display = display;
    paletteInfo.colormap = colormap;
    Hi240BuildPalette((ulong) 0x10000, (Hi240StorePaletteEntry *) StoreColormapEntry, &paletteInfo);
    XSetWindowColormap(display, window, colormap);
  } // end if

  // Create image

  if (image.Create(
    display,
    window, // Defines visual, depth
    MaxImageWidth,
    MaxImageHeight,
    True // MITSHM
    ) < 0) {
    printf("Error: image.Create() failed\n");
    exit(1);
  } // end if

  image.Clear();

#if (1)
  printf("\nDisplay:\n");
  printf("Image byte order = %s\n", ByteOrderName(ImageByteOrder(display)));
  printf("Bitmap unit      = %i\n", BitmapUnit(display));
  printf("Bitmap bit order = %s\n", ByteOrderName(BitmapBitOrder(display)));
  printf("Bitmap pad       = %i\n", BitmapPad(display));

  printf("\nWindow:\n");
  printf("Depth            = %i\n", windowAttributes.depth);
  printf("Visual ID        = 0x%02x\n", windowAttributes.visual->visualid);
  printf("Visual class     = %s\n", VisualClassName(windowAttributes.visual->c_class));
  printf("Red mask         = 0x%08lx\n", windowAttributes.visual->red_mask);
  printf("Green mask       = 0x%08lx\n", windowAttributes.visual->green_mask);
  printf("Blue mask        = 0x%08lx\n", windowAttributes.visual->blue_mask);
  printf("Bits per R/G/B   = %i\n", windowAttributes.visual->bits_per_rgb); // log2 # colors

  xImage = image.X();
  printf("\nImage:\n");
  printf("Image byte order = %s\n", ByteOrderName(xImage->byte_order));
  printf("Bitmap unit      = %i\n", xImage->bitmap_unit);
  printf("Bitmap bit order = %s\n", ByteOrderName(xImage->bitmap_bit_order));
  printf("Bitmap pad       = %i\n", xImage->bitmap_pad);
  printf("Depth            = %i\n", xImage->depth);
  printf("Red mask         = 0x%08lx\n", xImage->red_mask);
  printf("Green mask       = 0x%08lx\n", xImage->green_mask);
  printf("Blue mask        = 0x%08lx\n", xImage->blue_mask);
  printf("Bits per pixel   = %i\n", xImage->bits_per_pixel); // ZPixmap
  printf("Bytes per line   = %i\n", xImage->bytes_per_line);
  printf("IsShared         = %s\n", image.IsShared() ? "True" : "False");
  printf("HasSharedPixmap  = %s\n", image.HasSharedPixmap() ? "True" : "False");
#endif

  // V4L stuff

  if ((v4l = open(BigPictureDevice, O_RDWR)) < 0) {
    printf("Error: Can't open %s: %s\n", BigPictureDevice, strerror(errno));
    exit(1);
  } // end if

  if (V4LMGetMMInfo(v4l, &v4lMMInfo) < 0) {
    printf("Error: V4LMGetMMInfo: %s\n", strerror(errno));
    exit(1);
  } // end if
#if (0)
  printf("Capture buffer size   = %i\n", v4lMMInfo.size);
  printf("Capture buffer frames = %i\n", v4lMMInfo.frames);
#endif
  if (v4lMMInfo.frames < 2) {
    printf("Error: V4LMGetMMInfo: frames < 2\n");
    exit(1);
  } // end if

  if ((captureBuf = (bits8 *) mmap(0, v4lMMInfo.size, PROT_READ | PROT_WRITE, MAP_SHARED, v4l, 0)) == MAP_FAILED) {
    printf("Error: mmap(): %s\n", strerror(errno));
    exit(1);
  } // end if

  if (V4LSetSource(v4l, BigPictureCompositeSource, VIDEO_MODE_NTSC) < 0) {
    printf("Error: V4LSetSource: %s\n", strerror(errno));
    exit(1);
  } // end if

  if (V4LGetCaps(v4l, &v4lCaps) < 0) {
    printf("Error: V4LGetCaps: %s\n", strerror(errno));
    exit(1);
  } // end if

  // Select V4L RGB capture format to exactly match image/visual (no LUTs!)

  if ((captureFormat = XImageCaptureFormat(image.X())) < 0) {
    printf("Error: No  match for visual/image\n");
    exit(1);
  } // end if

  // Initialize capture size based on window size

  windowWidth = windowAttributes.width;
  windowHeight = windowAttributes.height;;

  WindowResize(v4l, windowWidth, windowHeight, magnification); // Does V4LMSetFormat().

  // Initialize picture attributes to mid-range

  V4LSetBrightness(v4l, 65535 / 2);
  V4LSetContrast(v4l, 65535 / 2);
  V4LSetSaturation(v4l, 65535 / 2);
  V4LSetHue(v4l, 65535 / 2);

  // Ready to start: Display window, select events, and initiate capture sequence

  XMapRaised(display, window);

  XSetWMProtocols(display, window, &atomWMDeleteWindow, 1);

  XSelectInput(display, window, StructureNotifyMask | ExposureMask);

  captureFrame = 0;

  if (V4LMCapture(v4l, captureFrame) < 0) {
    printf("Error: V4LMCapture: %s\n", strerror(errno));
    exit(1);
  } // end if

  while (1) {

    if (XPending(display) > 0) {

      XNextEvent(display, &event);

      switch (event.type) {
      case ClientMessage: // From WM
	if (event.xclient.data.l[0] == atomWMDeleteWindow) {
	  exit(0);
	} // end if
	break;
      case ConfigureNotify:
	sizeChanged = false;
	if (event.xconfigure.width != windowWidth) {
	  sizeChanged = true;
	  windowWidth = event.xconfigure.width;
	} // end if
	if (event.xconfigure.height != windowHeight) {
	  sizeChanged = true;
	  windowHeight = event.xconfigure.height;
	} // end if
	if (sizeChanged) {
	  image.Clear();
	  XClearWindow(display, window);
	  WindowResize(v4l, windowWidth, windowHeight, magnification);
	} // end if
	break;
      case Expose:
	if (event.xexpose.count == 0) {
	  Put(window, image);
	} // end if
	break;
      } // end switch

    } else {

      // Wait for this frame

      if (V4LMSync(v4l, captureFrame) < 0) {
	printf("Error: V4LMSync: %s\n", strerror(errno));
	exit(1);
      } // end if

      // Start capture for next frame

      if (V4LMCapture(v4l, 1 - captureFrame) < 0) {
	printf("Error: V4LMCapture: %s\n", strerror(errno));
	exit(1);
      } // end if

      Draw(image, captureBuf + v4lMMInfo.offsets[captureFrame], magnification);

      Put(window, image);

      captureFrame = 1 - captureFrame; // 0<->1

    } // endif 

  } // end while

  printf("Error: Fell out of event loop!\n");

  exit(1);

} // end main
예제 #17
0
void Texture::SaveToSystemMemory()
{
    if (isRenderTarget)
    {
        /*
            Do not save texture if autosave flag is false
         */
        if (!renderTargetAutosave)
            return;

        HRESULT hr = RenderManager::Instance()->GetD3DDevice()->TestCooperativeLevel();
        if (hr == D3DERR_DEVICELOST)
        {
            //if (!saveTexture)
            //Logger::FrameworkDebug("Trying to save to system memory rendertarget that was not saved before");
            return;
        }

        //	Render manager set this flag  when you set sprite as render target.
        if (!renderTargetModified)
            return;
        // Release should be after check that renderTargetModified.
        D3DSafeRelease(saveTexture);

        LPDIRECT3DDEVICE9 device = RenderManager::Instance()->GetD3DDevice();

        D3DSURFACE_DESC desc;
        id->GetLevelDesc(0, &desc);
        //Logger::FrameworkDebug("Saving render target to system memory: %s size: %d x %d format:%d", relativePathname.c_str(), width, height, desc.Format);
        /*
        HRESULT hr = device->CreateOffscreenPlainSurface(width, height, desc.Format, D3DPOOL_SYSTEMMEM, &saveSurface, NULL);
        DX_VERIFY(hr);
        */

        hr = device->CreateTexture(width, height,
                                   1/*means we create texture with 1 mipmap level*/,
                                   0,  desc.Format, D3DPOOL_SYSTEMMEM, &saveTexture, 0);
        RENDER_VERIFY(hr);

        LPDIRECT3DSURFACE9 renderTargetMainSurface;
        hr = id->GetSurfaceLevel(0, &renderTargetMainSurface);
        RENDER_VERIFY(hr);

        LPDIRECT3DSURFACE9 saveTextureMainSurface;
        hr = saveTexture->GetSurfaceLevel(0, &saveTextureMainSurface);
        RENDER_VERIFY(hr);

        hr = device->GetRenderTargetData(renderTargetMainSurface, saveTextureMainSurface);
        RENDER_VERIFY(hr);

        renderTargetModified = false;

#if 0
        //Image * image = new Image();
        Image * image = image->Create(width, height, FORMAT_RGBA8888);
        D3DLOCKED_RECT rect;
        hr = saveTexture->LockRect(0, &rect, 0, 0);
        if (FAILED(hr))
        {
            Logger::Error("[TextureDX9] Could not lock DirectX9 Texture.");
            return;
        }
        int32 pixelSizeInBits = GetPixelFormatSize(format);
        if (format ==  FORMAT_RGBA8888)
        {
            //int32 pitchInBytes =

            uint8 * destBits = (uint8*)image->GetData();
            uint8 * sourceBits = (uint8*)rect.pBits;
            for (uint32 h = 0; h < height * width; ++h)
            {
                uint32 b = sourceBits[0];
                uint32 g = sourceBits[1];
                uint32 r = sourceBits[2];
                uint32 a = sourceBits[3];

                destBits[0] = (uint8)r; //sourceBits[3];
                destBits[1] = (uint8)g; //sourceBits[0];
                destBits[2] = (uint8)b;//sourceBits[1];
                destBits[3] = (uint8)a;

                destBits += 4;
                sourceBits += 4;
            }
        }

        saveTexture->UnlockRect(0);
        image->Save(Format("FBO\\%s.png", relativePathname.c_str()));

        SafeRelease(image);
#endif



        D3DSafeRelease(renderTargetMainSurface);
        D3DSafeRelease(saveTextureMainSurface);
    }
}
예제 #18
0
bool Font::insertGlyph(Char character) {
	
	FT_Error error;
	FT_UInt glyphIndex = FT_Get_Char_Index(face, character);
	if(!glyphIndex) {
		insertPlaceholderGlyph(character);
		return false;
	}
	
	error = FT_Load_Glyph(face, glyphIndex, FT_LOAD_FORCE_AUTOHINT);
	if(error) {
		insertPlaceholderGlyph(character);
		return false;
	}
	
	error = FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL);
	if(error) {
		insertPlaceholderGlyph(character);
		return false;
	}
	
	// Fill in info for this glyph.
	Glyph & glyph = glyphs[character];
	glyph.index = glyphIndex;
	glyph.size.x = face->glyph->bitmap.width;
	glyph.size.y = face->glyph->bitmap.rows;
	glyph.advance.x = face->glyph->linearHoriAdvance / 65536.0f;
	glyph.advance.y = face->glyph->linearVertAdvance / 65536.0f;
	glyph.lsb_delta = face->glyph->lsb_delta;
	glyph.rsb_delta = face->glyph->rsb_delta;
	glyph.draw_offset.x = face->glyph->bitmap_left;
	glyph.draw_offset.y = face->glyph->bitmap_top - face->glyph->bitmap.rows;
	glyph.uv_start = Vec2f_ZERO;
	glyph.uv_end = Vec2f_ZERO;
	glyph.texture = 0;
	
	// Some glyphs like spaces have a size of 0...
	if(glyph.size.x != 0 && glyph.size.y != 0) {
		
		Image imgGlyph;
		imgGlyph.Create(glyph.size.x, glyph.size.y, Image::Format_A8);
		
		FT_Bitmap * srcBitmap = &face->glyph->bitmap;
		arx_assert(srcBitmap->pitch >= 0);
		arx_assert(unsigned(srcBitmap->pitch) == unsigned(srcBitmap->width));
		
		// Copy pixels
		unsigned char * src = srcBitmap->buffer;
		unsigned char * dst = imgGlyph.GetData();
		memcpy(dst, src, glyph.size.x * glyph.size.y);
		
		Vec2i offset;
		if(!textures->insertImage(imgGlyph, glyph.texture, offset)) {
			LogWarning << "Could not upload glyph for character U+" << std::hex << character
			           << " (" << util::encode<util::UTF8>(character) << ") in font "
			           << info.name;
			insertPlaceholderGlyph(character);
			return false;
		}
		
		// Compute UV mapping for each glyph.
		const float textureSize = textures->getTextureSize();
		glyph.uv_start = Vec2f(offset) / Vec2f(textureSize);
		glyph.uv_end = Vec2f(offset + glyph.size) / Vec2f(textureSize);
	}
	
	return true;
}
void GenerateNormalisationCubeMap(Image &posX, Image &negX, Image &posY, Image &negY, Image &posZ, Image &negZ, int size)
{
	float offset = 0.5f;
	float halfSize = size * 0.5f;
	Vec3 tmpVector;
	BYTE *pByte;

	BYTE *pixels = new BYTE[size * size * 3];

	// Positive X
	pByte = pixels;

	for(int i = 0; i < size; i++)
	{
		for(int j = 0; j < size; j++)
		{
			tmpVector.x = halfSize;
			tmpVector.y = -(i + offset - halfSize);
			tmpVector.z = -(j + offset - halfSize);

			tmpVector.Normalize();
			tmpVector = tmpVector * 0.5f + Vec3(0.5f, 0.5f, 0.5f);

			pByte[0] = (BYTE)(tmpVector.x * 255);
			pByte[1] = (BYTE)(tmpVector.y * 255);
			pByte[2] = (BYTE)(tmpVector.z * 255);

			pByte += 3;
		}
	}

	posX.Create(size, size, 3, IFORMAT_RGB, pixels);

	// Negative X
	pByte = pixels;

	for(int i = 0; i < size; i++)
	{
		for(int j = 0; j < size; j++)
		{
			tmpVector.x = -halfSize;
			tmpVector.y = -(i + offset - halfSize);
			tmpVector.z = j + offset - halfSize;

			tmpVector.Normalize();
            tmpVector = tmpVector * 0.5f + Vec3(0.5f, 0.5f, 0.5f);

			pByte[0] = (BYTE)(tmpVector.x * 255);
			pByte[1] = (BYTE)(tmpVector.y * 255);
			pByte[2] = (BYTE)(tmpVector.z * 255);

			pByte += 3;
		}
	}

	negX.Create(size, size, 3, IFORMAT_RGB, pixels);

	// Positive Y
	pByte = pixels;

	for(int i = 0; i < size; i++)
	{
		for(int j = 0; j < size; j++)
		{
			tmpVector.x = j + offset - halfSize;
			tmpVector.y = halfSize;
			tmpVector.z = i + offset - halfSize;

			tmpVector.Normalize();
			tmpVector = tmpVector * 0.5f + Vec3(0.5f, 0.5f, 0.5f);

			pByte[0] = (BYTE)(tmpVector.x * 255);
			pByte[1] = (BYTE)(tmpVector.y * 255);
			pByte[2] = (BYTE)(tmpVector.z * 255);

			pByte += 3;
		}
	}

	posY.Create(size, size, 3, IFORMAT_RGB, pixels);

	// Negative Y
	pByte = pixels;

	for(int i = 0; i < size; i++)
	{
		for(int j = 0; j < size; j++)
		{
			tmpVector.x = j + offset - halfSize;
			tmpVector.y = -halfSize;
			tmpVector.z = -(i + offset - halfSize);

			tmpVector.Normalize();
			tmpVector = tmpVector * 0.5f + Vec3(0.5f, 0.5f, 0.5f);

			pByte[0] = (BYTE)(tmpVector.x * 255);
			pByte[1] = (BYTE)(tmpVector.y * 255);
			pByte[2] = (BYTE)(tmpVector.z * 255);

			pByte += 3;
		}
	}

	negY.Create(size, size, 3, IFORMAT_RGB, pixels);

	// Positive Z
	pByte = pixels;

	for(int i = 0; i < size; i++)
	{
		for(int j = 0; j < size; j++)
		{
			tmpVector.x = j + offset - halfSize;
			tmpVector.y = -(i + offset - halfSize);
			tmpVector.z = halfSize;

			tmpVector.Normalize();
			tmpVector = tmpVector * 0.5f + Vec3(0.5f, 0.5f, 0.5f);

			pByte[0] = (BYTE)(tmpVector.x * 255);
			pByte[1] = (BYTE)(tmpVector.y * 255);
			pByte[2] = (BYTE)(tmpVector.z * 255);

			pByte += 3;
		}
	}

	posZ.Create(size, size, 3, IFORMAT_RGB, pixels);

	// Negative Z
	pByte = pixels;

	for(int i = 0; i < size; i++)
	{
		for(int j = 0; j < size; j++)
		{
			tmpVector.x = -(j + offset - halfSize);
			tmpVector.y = -(i + offset - halfSize);
			tmpVector.z = -halfSize;

			tmpVector.Normalize();
			tmpVector = tmpVector * 0.5f + Vec3(0.5f, 0.5f, 0.5f);

			pByte[0] = (BYTE)(tmpVector.x * 255);
			pByte[1] = (BYTE)(tmpVector.y * 255);
			pByte[2] = (BYTE)(tmpVector.z * 255);

			pByte += 3;
		}
	}

	negZ.Create(size, size, 3, IFORMAT_RGB, pixels);
}
예제 #20
0
int main(int argc, char* argv[])
{
  Image inputImage;
  string basename;
  Image histogramImage;
  Image fleshImage, nonFleshImage;
  int j;
  int u, v;
  int width, height;
  int r, g, b;
  double y, i, q;
  BayesianClassifier classifier;
  Matrix input;
  int classIndex = 0;
  int *histogram;
  int numBins = 256;
  double scaleFactor = 255;
  int intensity;
  int maxFreq = 0;
  int equalizationLevels = 20;
  int *frequencyLevels;
//  int *freqHistogram;
  int totalPixels;
//  int totalBins, currentLevel, currentBinLimit, currentFreqBin;
  int red, green, blue;
  int dotPos;
  double ratio;
  int classComponents[] = {2, 5};
  unsigned char* pixel;
  unsigned char* fleshPixel;
  unsigned char* nonFleshPixel;
  unsigned char white[] = {255, 255, 255};

  if ( argc < 4 )
    return 0;

  frequencyLevels = (int *)malloc(equalizationLevels * sizeof(int));

  input.SetSize(2, 1);
  classifier.Create(2, 2, classComponents);
  histogramImage.Create(256, 256);

  for (j = 1; j < argc; j++)
  {
    if ( !strcmp(argv[j], "-x") )
    {
      classIndex = 1;
      continue;
    }
    if ( inputImage.Load(argv[j]) )
    {
      if ( classIndex == 0 )
        printf("Processing hand image %s\n", argv[j]);
      else
        printf("Processing other image %s\n", argv[j]);
      basename = argv[j];
      dotPos = basename.rfind('.');
      if ( dotPos != (int)string::npos )
        basename = basename.substr(0, dotPos);
      width = inputImage.GetWidth();
      height = inputImage.GetHeight();
      if ( classIndex == 0 )
      {
        fleshImage.Create(width, height);
        nonFleshImage.Create(width, height);
      }
      pixel = inputImage.GetRGBBuffer();
      fleshPixel = fleshImage.GetRGBBuffer();
      nonFleshPixel = nonFleshImage.GetRGBBuffer();
      for (v = 0; v < height; v++)
      {
        for (u = 0; u < width; u++, pixel += 3, fleshPixel += 3, nonFleshPixel += 3)
        {
          r = pixel[0];
          g = pixel[1];
          b = pixel[2];
          y =   r * .299 + g *  .587 + b *  .114;
          i = ((r * .596 + g * -.275 + b * -.321)/.596 + 255)/2;
          q = ((r * .212 + g * -.523 + b *  .311)/.523 + 255)/2;

          if ( classIndex == 0 )
          {
            if (y <= 50)
            {
              // Pixel is not flesh colored
              memcpy(fleshPixel, white, 3);
              memcpy(nonFleshPixel, pixel, 3);
            }
            else
            {
              // Pixel is flesh colored
              memcpy(fleshPixel, pixel, 3);
              memcpy(nonFleshPixel, white, 3);
            }
          }

          if ( (classIndex == 0) && (y <= 50) )
            continue;

          input.SetValue(0, 0, i / 255);
          input.SetValue(1, 0, q / 255);
          classifier.AddTrainingData(input, classIndex);
        }
      }
      if ( classIndex == 0 )
      {
        fleshImage.Save(basename + "_flesh.png");
        nonFleshImage.Save(basename + "_nonflesh.png");
      }
    }
  }

  histogram = classifier.Get2dDataHistogram(0, numBins, scaleFactor);
  totalPixels = 0;
  for (v = 0; v < 256; v++)
    for (u = 0; u < 256; u++)
    {
      totalPixels += histogram[v * numBins + u];
      if ( histogram[v * numBins + u] > maxFreq )
        maxFreq = histogram[v * numBins + u];
    }
#if 0
  freqHistogram = (int *)malloc(maxFreq * sizeof(int));
  memset(freqHistogram, 0, maxFreq * sizeof(int));
  for (v = 0; v < 256; v++)
    for (u = 0; u < 256; u++)
      freqHistogram[histogram[v * numBins + u]]++;

  totalBins = 0;
  currentFreqBin = 0;
  for (currentLevel = 0; currentLevel < equalizationLevels; currentLevel++)
  {
    currentBinLimit = (int)(65536.0 / (equalizationLevels - 1) * (currentLevel + 1) + .5);
    while ( (currentFreqBin < maxFreq) && (totalBins < currentBinLimit) )
    {
      totalBins += freqHistogram[currentFreqBin];
      currentFreqBin++;
    }
    printf("Total bins %d\n", totalBins);
    frequencyLevels[currentLevel] = currentFreqBin;
    printf("Level %d - %d\n", currentLevel, frequencyLevels[currentLevel]);
  }
#endif

  printf("Flesh Max Freq %d\n", maxFreq);

  pixel = histogramImage.GetRGBBuffer();
  for (v = 0; v < 256; v++)
  {
    for (u = 0; u < 256; u++, pixel += 3)
    {
#if 1
#if 0
      if ( histogram[v * numBins + u] > 0 )
        printf("(%d, %d) %d\n", u, v, histogram[v * numBins + u]);
#endif
#if 0
      intensity = (int)(histogram[v * numBins + u] / (double)maxFreq * 255 + .5);
      pixel[0] = (unsigned char)intensity;
      pixel[1] = (unsigned char)intensity;
      pixel[2] = (unsigned char)intensity;
#else
      ratio = histogram[v * numBins + u] / (double)maxFreq * 0xffffff;
      red = (int)(ratio / 0x10000 + .5);
      if ( red > 0 )
        green = 255;
      else
        green = (int)(ratio / 0x100 + .5);
      if ( green > 0 )
        blue = 255;
      else
        blue = (int)(ratio + .5);
      pixel[0] = (unsigned char)red;
      pixel[1] = (unsigned char)green;
      pixel[2] = (unsigned char)blue;
#endif
#else
      for (currentLevel = 0; currentLevel < equalizationLevels; currentLevel++)
      {
        if ( histogram[v * numBins + u] < frequencyLevels[currentLevel] )
          intensity = (int)(currentLevel * 256.0 / (equalizationLevels - 1) + .5);
        else
          break;
      }
      histogramImage.setPixel(u, v, qRgb(intensity, intensity, intensity));
#endif
    }
  }
  histogramImage.Save("FleshCluster.png");

  maxFreq = 0;
  totalPixels = 0;
  histogram = classifier.Get2dDataHistogram(1, numBins, scaleFactor);
  for (v = 0; v < 256; v++)
    for (u = 0; u < 256; u++)
    {
      totalPixels += histogram[v * numBins + u];
      if ( histogram[v * numBins + u] > maxFreq )
        maxFreq = histogram[v * numBins + u];
    }

  printf("Non Flesh Max Freq %d\n", maxFreq);

  pixel = histogramImage.GetRGBBuffer();
  for (v = 0; v < 256; v++)
  {
    for (u = 0; u < 256; u++, pixel += 3)
    {
#if 0
      intensity = (int)(histogram[v * numBins + u] / (double)maxFreq * 255 + .5);
      pixel[0] = (unsigned char)intensity;
      pixel[1] = (unsigned char)intensity;
      pixel[2] = (unsigned char)intensity;
#else
      ratio = histogram[v * numBins + u] / (double)maxFreq * 0xffffff;
      red = (int)(ratio / 0x10000 + .5);
      if ( red > 0 )
        green = 255;
      else
        green = (int)(ratio / 0x100 + .5);
      if ( green > 0 )
        blue = 255;
      else
        blue = (int)(ratio + .5);
      pixel[0] = (unsigned char)red;
      pixel[1] = (unsigned char)green;
      pixel[2] = (unsigned char)blue;
#endif
    }
  }
  histogramImage.Save("NonFleshClusterl.png");

  free(frequencyLevels);
  return 0;
}