<commit_before>/* Copyright 2013 Jeremie Roy. All rights reserved.
 * License: http://www.opensource.org/licenses/BSD-2-Clause
*/
#include "TrueTypeFont.h"
/*
#undef __FTERRORS_H__
#define FT_ERRORDEF( e, v, s )  { e, s },
#define FT_ERROR_START_LIST     {
#define FT_ERROR_END_LIST       { 0, 0 } };
const struct {
    int          code;
    const char*  message;
} FT_Errors[] =
*/
#include "FreeType.h"
#include "edtaa3func.h"
//#include "SEDT.h"
#include <assert.h>
#include <math.h>

struct FTHolder
{
	FT_Library library;
	FT_Face face;
};

namespace bgfx_font
{

TrueTypeFont::TrueTypeFont(): m_font(NULL)
{
}

TrueTypeFont::~TrueTypeFont()
{
	if(m_font!=NULL)
	{
		FTHolder* holder = (FTHolder*) m_font;
		FT_Done_Face( holder->face );
        FT_Done_FreeType( holder->library );
		delete m_font;
		m_font = NULL;
	}
}

bool TrueTypeFont::init(const uint8_t* buffer, uint32_t bufferSize, int32_t fontIndex, uint32_t pixelHeight)
{
	assert((bufferSize > 256 && bufferSize < 100000000) && "TrueType buffer size is suspicious");
	assert((pixelHeight > 4 && pixelHeight < 128) && "TrueType buffer size is suspicious");

	assert(m_font == NULL && "TrueTypeFont already initialized" );

	FTHolder* holder = new FTHolder();

	// Initialize Freetype library
	FT_Error error = FT_Init_FreeType( &holder->library );
	if( error)
	{
		delete holder;
		return false;
	}

	error = FT_New_Memory_Face( holder->library, buffer, bufferSize, fontIndex, &holder->face );
	if ( error == FT_Err_Unknown_File_Format )
	{
		// the font file could be opened and read, but it appears
		//that its font format is unsupported
		FT_Done_FreeType( holder->library );
		delete holder;
		return false;
	}
	else if ( error )
	{
		// another error code means that the font file could not
		// be opened or read, or simply that it is broken...
		FT_Done_FreeType( holder->library );
		delete holder;
		return false;
	}

    // Select unicode charmap
    error = FT_Select_Charmap( holder->face, FT_ENCODING_UNICODE );
    if( error )
    {
		FT_Done_Face( holder->face );
		FT_Done_FreeType( holder->library );
        return false;
    }
	//set size in pixels
	error = FT_Set_Pixel_Sizes( holder->face, 0, pixelHeight );
	if( error )
    {
		FT_Done_Face( holder->face );
		FT_Done_FreeType( holder->library );
        return false;
    }

	m_font = holder;
	return true;
}

FontInfo TrueTypeFont::getFontInfo()
{
	assert(m_font != NULL && "TrueTypeFont not initialized" );
	FTHolder* holder = (FTHolder*) m_font;

	assert(FT_IS_SCALABLE (holder->face));

	FT_Size_Metrics metrics = holder->face->size->metrics;

	//todo manage unscalable font
	FontInfo outFontInfo;
	outFontInfo.scale = 1.0f;
	outFontInfo.ascender = metrics.ascender /64.0f;
	outFontInfo.descender = metrics.descender /64.0f;
	outFontInfo.lineGap = (metrics.height - metrics.ascender + metrics.descender) /64.0f;

	outFontInfo.underline_position = FT_MulFix(holder->face->underline_position, metrics.y_scale) /64.0f;
	outFontInfo.underline_thickness= FT_MulFix(holder->face->underline_thickness,metrics.y_scale) /64.0f;
	return outFontInfo;
}

bool TrueTypeFont::bakeGlyphAlpha(const FontInfo& fontInfo,CodePoint_t codePoint, GlyphInfo& glyphInfo, uint8_t* outBuffer)
{
	assert(m_font != NULL && "TrueTypeFont not initialized" );
	FTHolder* holder = (FTHolder*) m_font;

	glyphInfo.glyphIndex = FT_Get_Char_Index( holder->face, codePoint );

	FT_GlyphSlot slot = holder->face->glyph;
	FT_Error error = FT_Load_Glyph(  holder->face, glyphInfo.glyphIndex, FT_LOAD_DEFAULT );
	if(error) { return false; }

	FT_Glyph glyph;
	error = FT_Get_Glyph( slot, &glyph );
	if ( error ) { return false; }

	error = FT_Glyph_To_Bitmap( &glyph, FT_RENDER_MODE_NORMAL, 0, 1 );
	if(error){ return false; }

	FT_BitmapGlyph bitmap = (FT_BitmapGlyph)glyph;

	int x = bitmap->left;
	int y = -bitmap->top;
	int w = bitmap->bitmap.width;
	int h = bitmap->bitmap.rows;

	glyphInfo.offset_x = (float) x;
	glyphInfo.offset_y = (float) y;
	glyphInfo.width = (float) w;
	glyphInfo.height = (float) h;
	glyphInfo.advance_x = (float)slot->advance.x /64.0f;
	glyphInfo.advance_y = (float)slot->advance.y /64.0f;

	int charsize = 1;
	int depth=1;
	int stride = bitmap->bitmap.pitch;
	for( int i=0; i<h; ++i )
    {
        memcpy(outBuffer+(i*w) * charsize * depth,
			bitmap->bitmap.buffer + (i*stride) * charsize, w * charsize * depth  );
    }
	FT_Done_Glyph(glyph);
	return true;
}

bool TrueTypeFont::bakeGlyphSubpixel(const FontInfo& fontInfo,CodePoint_t codePoint, GlyphInfo& glyphInfo, uint8_t* outBuffer)
{
	assert(m_font != NULL && "TrueTypeFont not initialized" );
	FTHolder* holder = (FTHolder*) m_font;

	glyphInfo.glyphIndex = FT_Get_Char_Index( holder->face, codePoint );

	FT_GlyphSlot slot = holder->face->glyph;
	FT_Error error = FT_Load_Glyph(  holder->face, glyphInfo.glyphIndex, FT_LOAD_DEFAULT );
	if(error) { return false; }

	FT_Glyph glyph;
	error = FT_Get_Glyph( slot, &glyph );
	if ( error ) { return false; }

	error = FT_Glyph_To_Bitmap( &glyph, FT_RENDER_MODE_LCD, 0, 1 );
	if(error){ return false; }

	FT_BitmapGlyph bitmap = (FT_BitmapGlyph)glyph;
	int x = bitmap->left;
	int y = -bitmap->top;
	int w = bitmap->bitmap.width;
	int h = bitmap->bitmap.rows;

	glyphInfo.offset_x = (float) x;
	glyphInfo.offset_y = (float) y;
	glyphInfo.width = (float) w;
	glyphInfo.height = (float) h;
	glyphInfo.advance_x = (float)slot->advance.x /64.0f;
	glyphInfo.advance_y = (float)slot->advance.y /64.0f;
	int charsize = 1;
	int depth=3;
	int stride = bitmap->bitmap.pitch;
	for( int i=0; i<h; ++i )
    {
        memcpy(outBuffer+(i*w) * charsize * depth,
			bitmap->bitmap.buffer + (i*stride) * charsize, w * charsize * depth  );
    }
	FT_Done_Glyph(glyph);
	return true;
}

void make_distance_map( unsigned char *img, unsigned char *outImg, unsigned int width, unsigned int height )
{
    short * xdist = (short *)  malloc( width * height * sizeof(short) );
    short * ydist = (short *)  malloc( width * height * sizeof(short) );
    double * gx   = (double *) calloc( width * height, sizeof(double) );
    double * gy      = (double *) calloc( width * height, sizeof(double) );
    double * data    = (double *) calloc( width * height, sizeof(double) );
    double * outside = (double *) calloc( width * height, sizeof(double) );
    double * inside  = (double *) calloc( width * height, sizeof(double) );
    uint32_t i;

    // Convert img into double (data)
    double img_min = 255, img_max = -255;
    for( i=0; i<width*height; ++i)
    {
        double v = img[i];
        data[i] = v;
        if (v > img_max) img_max = v;
        if (v < img_min) img_min = v;
    }
    // Rescale image levels between 0 and 1
    for( i=0; i<width*height; ++i)
    {
        data[i] = (img[i]-img_min)/(img_max-img_min);
    }

    // Compute outside = edtaa3(bitmap); % Transform background (0's)
    computegradient( data, width, height, gx, gy);
    edtaa3(data, gx, gy, width, height, xdist, ydist, outside);
    for( i=0; i<width*height; ++i)
        if( outside[i] < 0 )
            outside[i] = 0.0;

    // Compute inside = edtaa3(1-bitmap); % Transform foreground (1's)
    memset(gx, 0, sizeof(double)*width*height );
    memset(gy, 0, sizeof(double)*width*height );
    for( i=0; i<width*height; ++i)
        data[i] = 1.0 - data[i];
    computegradient( data, width, height, gx, gy);
    edtaa3(data, gx, gy, width, height, xdist, ydist, inside);
    for( i=0; i<width*height; ++i)
        if( inside[i] < 0 )
            inside[i] = 0.0;

    // distmap = outside - inside; % Bipolar distance field
    unsigned char *out = outImg;//(unsigned char *) malloc( width * height * sizeof(unsigned char) );
    for( i=0; i<width*height; ++i)
    {
		//out[i] = 127 - outside[i]*8;
		//if(out[i]<0) out[i] = 0;
		//out[i] += inside[i]*16;
		//if(out[i]>255) out[i] = 255;

		outside[i] -= inside[i];
        outside[i] = 128 + outside[i]*16;

		//if(outside[i] > 8) outside[i] = 8;
		//if(inside[i] > 8) outside[i] = 8;

		//outside[i] = 128 - inside[i]*8 + outside[i]*8;

        if( outside[i] < 0 ) outside[i] = 0;
        if( outside[i] > 255 ) outside[i] = 255;
        out[i] = 255 - (unsigned char) outside[i];
        //out[i] = (unsigned char) outside[i];
    }

    free( xdist );
    free( ydist );
    free( gx );
    free( gy );
    free( data );
    free( outside );
    free( inside );
}

bool TrueTypeFont::bakeGlyphDistance(const FontInfo& fontInfo, CodePoint_t codePoint, GlyphInfo& glyphInfo, uint8_t* outBuffer)
{
	assert(m_font != NULL && "TrueTypeFont not initialized" );
	FTHolder* holder = (FTHolder*) m_font;

	glyphInfo.glyphIndex = FT_Get_Char_Index( holder->face, codePoint );

	FT_Int32 loadMode = FT_LOAD_DEFAULT; //FT_LOAD_TARGET_MONO;
	FT_Render_Mode renderMode = FT_RENDER_MODE_NORMAL;//FT_RENDER_MODE_MONO

	FT_GlyphSlot slot = holder->face->glyph;
	FT_Error error = FT_Load_Glyph(  holder->face, glyphInfo.glyphIndex, loadMode );
	if(error) { return false; }

	FT_Glyph glyph;
	error = FT_Get_Glyph( slot, &glyph );
	if ( error ) { return false; }

	error = FT_Glyph_To_Bitmap( &glyph, renderMode, 0, 1 );
	if(error){ return false; }

	FT_BitmapGlyph bitmap = (FT_BitmapGlyph)glyph;

	int x = bitmap->left;
	int y = -bitmap->top;
	int w = bitmap->bitmap.width;
	int h = bitmap->bitmap.rows;

	glyphInfo.offset_x = (float) x;
	glyphInfo.offset_y = (float) y;
	glyphInfo.width = (float) w;
	glyphInfo.height = (float) h;
	glyphInfo.advance_x = (float)slot->advance.x /64.0f;
	glyphInfo.advance_y = (float)slot->advance.y /64.0f;

	int charsize = 1;
	int depth=1;
	int stride = bitmap->bitmap.pitch;

	/*
	const uint8_t* src = bitmap->bitmap.buffer;
	for( int y=0; y<h; ++y )
	{
		for( int x=0; x<w; ++x )
		{
			uint32_t idx = y*w+x;
			outBuffer[idx] = ((src[x / 8]) & (1 << (7 - (x % 8)))) ? 255 : 0;
		}
		src+=stride;
	}*/

	for( int i=0; i<h; ++i )
    {

        memcpy(outBuffer+(i*w) * charsize * depth,
			bitmap->bitmap.buffer + (i*stride) * charsize, w * charsize * depth  );
    }
	FT_Done_Glyph(glyph);

	if(w*h >0)
	{
		uint32_t dw = 6;
		uint32_t dh = 6;
		if(dw<2) dw = 2;
		if(dh<2) dh = 2;

		uint32_t nw = w + dw*2;
		uint32_t nh = h + dh*2;
		assert(nw*nh < 128*128);
		uint32_t buffSize = nw*nh*sizeof(uint8_t);

		uint8_t * alphaImg = (uint8_t *)  malloc( buffSize );
		memset(alphaImg, 0, nw*nh*sizeof(uint8_t));

		//copy the original buffer to the temp one
		for(uint32_t  i= dh; i< nh-dh; ++i)
		{
			memcpy(alphaImg+i*nw+dw, outBuffer+(i-dh)*w, w);
		}

		make_distance_map(alphaImg, outBuffer, nw, nh);
		free(alphaImg);

		glyphInfo.offset_x -= (float) dw;
		glyphInfo.offset_y -= (float) dh;
		glyphInfo.width = (float) nw ;
		glyphInfo.height = (float) nh;
	}

	return true;
}

}
<commit_msg>disable hinting for distance font<commit_after>/* Copyright 2013 Jeremie Roy. All rights reserved.
 * License: http://www.opensource.org/licenses/BSD-2-Clause
*/
#include "TrueTypeFont.h"
/*
#undef __FTERRORS_H__
#define FT_ERRORDEF( e, v, s )  { e, s },
#define FT_ERROR_START_LIST     {
#define FT_ERROR_END_LIST       { 0, 0 } };
const struct {
    int          code;
    const char*  message;
} FT_Errors[] =
*/
#include "FreeType.h"
#include "edtaa3func.h"
//#include "SEDT.h"
#include <assert.h>
#include <math.h>

struct FTHolder
{
	FT_Library library;
	FT_Face face;
};

namespace bgfx_font
{

TrueTypeFont::TrueTypeFont(): m_font(NULL)
{
}

TrueTypeFont::~TrueTypeFont()
{
	if(m_font!=NULL)
	{
		FTHolder* holder = (FTHolder*) m_font;
		FT_Done_Face( holder->face );
        FT_Done_FreeType( holder->library );
		delete m_font;
		m_font = NULL;
	}
}

bool TrueTypeFont::init(const uint8_t* buffer, uint32_t bufferSize, int32_t fontIndex, uint32_t pixelHeight)
{
	assert((bufferSize > 256 && bufferSize < 100000000) && "TrueType buffer size is suspicious");
	assert((pixelHeight > 4 && pixelHeight < 128) && "TrueType buffer size is suspicious");

	assert(m_font == NULL && "TrueTypeFont already initialized" );

	FTHolder* holder = new FTHolder();

	// Initialize Freetype library
	FT_Error error = FT_Init_FreeType( &holder->library );
	if( error)
	{
		delete holder;
		return false;
	}

	error = FT_New_Memory_Face( holder->library, buffer, bufferSize, fontIndex, &holder->face );
	if ( error == FT_Err_Unknown_File_Format )
	{
		// the font file could be opened and read, but it appears
		//that its font format is unsupported
		FT_Done_FreeType( holder->library );
		delete holder;
		return false;
	}
	else if ( error )
	{
		// another error code means that the font file could not
		// be opened or read, or simply that it is broken...
		FT_Done_FreeType( holder->library );
		delete holder;
		return false;
	}

    // Select unicode charmap
    error = FT_Select_Charmap( holder->face, FT_ENCODING_UNICODE );
    if( error )
    {
		FT_Done_Face( holder->face );
		FT_Done_FreeType( holder->library );
        return false;
    }
	//set size in pixels
	error = FT_Set_Pixel_Sizes( holder->face, 0, pixelHeight );
	if( error )
    {
		FT_Done_Face( holder->face );
		FT_Done_FreeType( holder->library );
        return false;
    }

	m_font = holder;
	return true;
}

FontInfo TrueTypeFont::getFontInfo()
{
	assert(m_font != NULL && "TrueTypeFont not initialized" );
	FTHolder* holder = (FTHolder*) m_font;

	assert(FT_IS_SCALABLE (holder->face));

	FT_Size_Metrics metrics = holder->face->size->metrics;

	//todo manage unscalable font
	FontInfo outFontInfo;
	outFontInfo.scale = 1.0f;
	outFontInfo.ascender = metrics.ascender /64.0f;
	outFontInfo.descender = metrics.descender /64.0f;
	outFontInfo.lineGap = (metrics.height - metrics.ascender + metrics.descender) /64.0f;

	outFontInfo.underline_position = FT_MulFix(holder->face->underline_position, metrics.y_scale) /64.0f;
	outFontInfo.underline_thickness= FT_MulFix(holder->face->underline_thickness,metrics.y_scale) /64.0f;
	return outFontInfo;
}

bool TrueTypeFont::bakeGlyphAlpha(const FontInfo& fontInfo,CodePoint_t codePoint, GlyphInfo& glyphInfo, uint8_t* outBuffer)
{
	assert(m_font != NULL && "TrueTypeFont not initialized" );
	FTHolder* holder = (FTHolder*) m_font;

	glyphInfo.glyphIndex = FT_Get_Char_Index( holder->face, codePoint );

	FT_GlyphSlot slot = holder->face->glyph;
	FT_Error error = FT_Load_Glyph(  holder->face, glyphInfo.glyphIndex, FT_LOAD_DEFAULT );
	if(error) { return false; }

	FT_Glyph glyph;
	error = FT_Get_Glyph( slot, &glyph );
	if ( error ) { return false; }

	error = FT_Glyph_To_Bitmap( &glyph, FT_RENDER_MODE_NORMAL, 0, 1 );
	if(error){ return false; }

	FT_BitmapGlyph bitmap = (FT_BitmapGlyph)glyph;

	int x = bitmap->left;
	int y = -bitmap->top;
	int w = bitmap->bitmap.width;
	int h = bitmap->bitmap.rows;

	glyphInfo.offset_x = (float) x;
	glyphInfo.offset_y = (float) y;
	glyphInfo.width = (float) w;
	glyphInfo.height = (float) h;
	glyphInfo.advance_x = (float)slot->advance.x /64.0f;
	glyphInfo.advance_y = (float)slot->advance.y /64.0f;

	int charsize = 1;
	int depth=1;
	int stride = bitmap->bitmap.pitch;
	for( int i=0; i<h; ++i )
    {
        memcpy(outBuffer+(i*w) * charsize * depth,
			bitmap->bitmap.buffer + (i*stride) * charsize, w * charsize * depth  );
    }
	FT_Done_Glyph(glyph);
	return true;
}

bool TrueTypeFont::bakeGlyphSubpixel(const FontInfo& fontInfo,CodePoint_t codePoint, GlyphInfo& glyphInfo, uint8_t* outBuffer)
{
	assert(m_font != NULL && "TrueTypeFont not initialized" );
	FTHolder* holder = (FTHolder*) m_font;

	glyphInfo.glyphIndex = FT_Get_Char_Index( holder->face, codePoint );

	FT_GlyphSlot slot = holder->face->glyph;
	FT_Error error = FT_Load_Glyph(  holder->face, glyphInfo.glyphIndex, FT_LOAD_DEFAULT );
	if(error) { return false; }

	FT_Glyph glyph;
	error = FT_Get_Glyph( slot, &glyph );
	if ( error ) { return false; }

	error = FT_Glyph_To_Bitmap( &glyph, FT_RENDER_MODE_LCD, 0, 1 );
	if(error){ return false; }

	FT_BitmapGlyph bitmap = (FT_BitmapGlyph)glyph;
	int x = bitmap->left;
	int y = -bitmap->top;
	int w = bitmap->bitmap.width;
	int h = bitmap->bitmap.rows;

	glyphInfo.offset_x = (float) x;
	glyphInfo.offset_y = (float) y;
	glyphInfo.width = (float) w;
	glyphInfo.height = (float) h;
	glyphInfo.advance_x = (float)slot->advance.x /64.0f;
	glyphInfo.advance_y = (float)slot->advance.y /64.0f;
	int charsize = 1;
	int depth=3;
	int stride = bitmap->bitmap.pitch;
	for( int i=0; i<h; ++i )
    {
        memcpy(outBuffer+(i*w) * charsize * depth,
			bitmap->bitmap.buffer + (i*stride) * charsize, w * charsize * depth  );
    }
	FT_Done_Glyph(glyph);
	return true;
}

void make_distance_map( unsigned char *img, unsigned char *outImg, unsigned int width, unsigned int height )
{
    short * xdist = (short *)  malloc( width * height * sizeof(short) );
    short * ydist = (short *)  malloc( width * height * sizeof(short) );
    double * gx   = (double *) calloc( width * height, sizeof(double) );
    double * gy      = (double *) calloc( width * height, sizeof(double) );
    double * data    = (double *) calloc( width * height, sizeof(double) );
    double * outside = (double *) calloc( width * height, sizeof(double) );
    double * inside  = (double *) calloc( width * height, sizeof(double) );
    uint32_t i;

    // Convert img into double (data)
    double img_min = 255, img_max = -255;
    for( i=0; i<width*height; ++i)
    {
        double v = img[i];
        data[i] = v;
        if (v > img_max) img_max = v;
        if (v < img_min) img_min = v;
    }
    // Rescale image levels between 0 and 1
    for( i=0; i<width*height; ++i)
    {
        data[i] = (img[i]-img_min)/(img_max-img_min);
    }

    // Compute outside = edtaa3(bitmap); % Transform background (0's)
    computegradient( data, width, height, gx, gy);
    edtaa3(data, gx, gy, width, height, xdist, ydist, outside);
    for( i=0; i<width*height; ++i)
        if( outside[i] < 0 )
            outside[i] = 0.0;

    // Compute inside = edtaa3(1-bitmap); % Transform foreground (1's)
    memset(gx, 0, sizeof(double)*width*height );
    memset(gy, 0, sizeof(double)*width*height );
    for( i=0; i<width*height; ++i)
        data[i] = 1.0 - data[i];
    computegradient( data, width, height, gx, gy);
    edtaa3(data, gx, gy, width, height, xdist, ydist, inside);
    for( i=0; i<width*height; ++i)
        if( inside[i] < 0 )
            inside[i] = 0.0;

    // distmap = outside - inside; % Bipolar distance field
    unsigned char *out = outImg;//(unsigned char *) malloc( width * height * sizeof(unsigned char) );
    for( i=0; i<width*height; ++i)
    {
		//out[i] = 127 - outside[i]*8;
		//if(out[i]<0) out[i] = 0;
		//out[i] += inside[i]*16;
		//if(out[i]>255) out[i] = 255;

		outside[i] -= inside[i];
        outside[i] = 128 + outside[i]*16;

		//if(outside[i] > 8) outside[i] = 8;
		//if(inside[i] > 8) outside[i] = 8;

		//outside[i] = 128 - inside[i]*8 + outside[i]*8;

        if( outside[i] < 0 ) outside[i] = 0;
        if( outside[i] > 255 ) outside[i] = 255;
        out[i] = 255 - (unsigned char) outside[i];
        //out[i] = (unsigned char) outside[i];
    }

    free( xdist );
    free( ydist );
    free( gx );
    free( gy );
    free( data );
    free( outside );
    free( inside );
}

bool TrueTypeFont::bakeGlyphDistance(const FontInfo& fontInfo, CodePoint_t codePoint, GlyphInfo& glyphInfo, uint8_t* outBuffer)
{
	assert(m_font != NULL && "TrueTypeFont not initialized" );
	FTHolder* holder = (FTHolder*) m_font;

	glyphInfo.glyphIndex = FT_Get_Char_Index( holder->face, codePoint );

	FT_Int32 loadMode = FT_LOAD_DEFAULT|FT_LOAD_NO_HINTING; //FT_LOAD_TARGET_MONO;
	FT_Render_Mode renderMode = FT_RENDER_MODE_NORMAL;//FT_RENDER_MODE_MONO

	FT_GlyphSlot slot = holder->face->glyph;
	FT_Error error = FT_Load_Glyph(  holder->face, glyphInfo.glyphIndex, loadMode );
	if(error) { return false; }

	FT_Glyph glyph;
	error = FT_Get_Glyph( slot, &glyph );
	if ( error ) { return false; }

	error = FT_Glyph_To_Bitmap( &glyph, renderMode, 0, 1 );
	if(error){ return false; }

	FT_BitmapGlyph bitmap = (FT_BitmapGlyph)glyph;

	int x = bitmap->left;
	int y = -bitmap->top;
	int w = bitmap->bitmap.width;
	int h = bitmap->bitmap.rows;

	glyphInfo.offset_x = (float) x;
	glyphInfo.offset_y = (float) y;
	glyphInfo.width = (float) w;
	glyphInfo.height = (float) h;
	glyphInfo.advance_x = (float)slot->advance.x /64.0f;
	glyphInfo.advance_y = (float)slot->advance.y /64.0f;

	int charsize = 1;
	int depth=1;
	int stride = bitmap->bitmap.pitch;

	/*
	const uint8_t* src = bitmap->bitmap.buffer;
	for( int y=0; y<h; ++y )
	{
		for( int x=0; x<w; ++x )
		{
			uint32_t idx = y*w+x;
			outBuffer[idx] = ((src[x / 8]) & (1 << (7 - (x % 8)))) ? 255 : 0;
		}
		src+=stride;
	}*/

	for( int i=0; i<h; ++i )
    {

        memcpy(outBuffer+(i*w) * charsize * depth,
			bitmap->bitmap.buffer + (i*stride) * charsize, w * charsize * depth  );
    }
	FT_Done_Glyph(glyph);

	if(w*h >0)
	{
		uint32_t dw = 6;
		uint32_t dh = 6;
		if(dw<2) dw = 2;
		if(dh<2) dh = 2;

		uint32_t nw = w + dw*2;
		uint32_t nh = h + dh*2;
		assert(nw*nh < 128*128);
		uint32_t buffSize = nw*nh*sizeof(uint8_t);

		uint8_t * alphaImg = (uint8_t *)  malloc( buffSize );
		memset(alphaImg, 0, nw*nh*sizeof(uint8_t));

		//copy the original buffer to the temp one
		for(uint32_t  i= dh; i< nh-dh; ++i)
		{
			memcpy(alphaImg+i*nw+dw, outBuffer+(i-dh)*w, w);
		}

		make_distance_map(alphaImg, outBuffer, nw, nh);
		free(alphaImg);

		glyphInfo.offset_x -= (float) dw;
		glyphInfo.offset_y -= (float) dh;
		glyphInfo.width = (float) nw ;
		glyphInfo.height = (float) nh;
	}

	return true;
}

}
<|endoftext|>


<commit_before>#include "GUINode.h"

wxIMPLEMENT_DYNAMIC_CLASS(GUINode, wxControl);

void GUINode::Init()
{
	// Compute the best width
	m_bestSize.SetWidth(200); // Must be computed depending on the lengths of the inputs and outputs parameters
	// Compute the best height
	int nbInputs = m_node.GetInputs().size();
	int nbOutputs = m_node.GetOutputs().size();
	m_maxParamsPerColumn = nbInputs > nbOutputs ? nbInputs : nbOutputs;
	m_bestSize.SetHeight((1 + m_maxParamsPerColumn) * 50); // MAGIC NUMBER here : we say 50 pixels per param and 50 pixels for the node's name

	// Defines the size of the widget
	SetSize(m_bestSize);

	// Add a sizer to manage the space inside the node
	wxSizer* verticalSizer = new wxBoxSizer(wxVERTICAL);
	wxStaticText* titleText = new wxStaticText(this, wxID_ANY, "Title");
	verticalSizer->Add(titleText, 1, wxALL | wxALIGN_CENTER);
	SetSizer(verticalSizer);
	Layout();
	SetBackgroundColour(*wxGREEN);

	titleText->Bind(wxEVT_MOTION, &GUINode::OnMouseMotion, this);
	titleText->Bind(wxEVT_LEFT_DOWN, &GUINode::OnLeftMouseDown, this);

	Bind(wxEVT_LEFT_DOWN, &GUINode::OnLeftMouseDown, this);
	Bind(wxEVT_LEFT_UP, &GUINode::OnLeftMouseUp, this);
	Bind(wxEVT_MOTION, &GUINode::OnMouseMotion, this);
	Bind(wxEVT_PAINT, &GUINode::OnPaint, this);
}

wxSize GUINode::DoGetBestSize() const
{
	return m_bestSize;
}

void GUINode::OnPaint(wxPaintEvent &event)
{
	wxPaintDC dc(this);
	wxGraphicsContext *gc = wxGraphicsContext::Create(dc);
	wxFont font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);

	int height = GetSize().GetHeight() - 1;
	int width = GetSize().GetWidth() - 1;
	int i = 0;
	if (gc)
	{
		// Draw the body
		gc->SetBrush(*wxRED_BRUSH);
		gc->SetPen(wxPen(*wxBLACK, 1));
		gc->DrawRoundedRectangle(0, 0, m_bestSize.GetWidth() - 1, m_bestSize.GetHeight() - 1, 10);

		gc->SetBrush(*wxBLUE_BRUSH);
		gc->SetFont(font, *wxBLACK);
		i = 0;
		// Draw the inputs
		for (InputParam p : m_node.GetInputs()) {
			gc->DrawEllipse(10, (i+0.5f)*height / m_maxParamsPerColumn, 25, 25);
			gc->DrawText(p.GetName(), 50, (i + 0.5f)*height / m_maxParamsPerColumn);
			i++;
		}
		i = 0;
		// Draw the outputs
		for (OutputParam p : m_node.GetOutputs()) {
			gc->DrawEllipse(width-50, (i+0.5f)*height / m_maxParamsPerColumn, 25, 25);
			gc->DrawText(p.GetName(), width-100, (i + 0.5f)*height / m_maxParamsPerColumn);
			i++;
		}

		delete gc;
	}

	event.Skip();
}

void GUINode::OnLeftMouseDown(wxMouseEvent& event)
{
	m_isDragging = true;
	m_firstDraggingPoint = ScreenToClient(ClientToScreen(event.GetPosition()));
}

void GUINode::OnLeftMouseUp(wxMouseEvent& event)
{
	m_isDragging = false;
}

void GUINode::OnMouseMotion(wxMouseEvent& event)
{
	if (m_isDragging && event.LeftIsDown())
		SetPosition(m_parent->ScreenToClient(ClientToScreen(event.GetPosition())) - m_firstDraggingPoint);
}<commit_msg>Bound the LeftMouseUp event of the textTitle to its parent (GUINode)<commit_after>#include "GUINode.h"

wxIMPLEMENT_DYNAMIC_CLASS(GUINode, wxControl);

void GUINode::Init()
{
	// Compute the best width
	m_bestSize.SetWidth(200); // Must be computed depending on the lengths of the inputs and outputs parameters
	// Compute the best height
	int nbInputs = m_node.GetInputs().size();
	int nbOutputs = m_node.GetOutputs().size();
	m_maxParamsPerColumn = nbInputs > nbOutputs ? nbInputs : nbOutputs;
	m_bestSize.SetHeight((1 + m_maxParamsPerColumn) * 50); // MAGIC NUMBER here : we say 50 pixels per param and 50 pixels for the node's name

	// Defines the size of the widget
	SetSize(m_bestSize);

	// Add a sizer to manage the space inside the node
	wxSizer* verticalSizer = new wxBoxSizer(wxVERTICAL);
	wxStaticText* titleText = new wxStaticText(this, wxID_ANY, "Title");
	verticalSizer->Add(titleText, 1, wxALL | wxALIGN_CENTER);

	// TODO Add horizontal sizers to distribute the space for each input/output

	SetSizer(verticalSizer);
	Layout();
	SetBackgroundColour(*wxGREEN);

	titleText->Bind(wxEVT_MOTION, &GUINode::OnMouseMotion, this);
	titleText->Bind(wxEVT_LEFT_DOWN, &GUINode::OnLeftMouseDown, this);
	titleText->Bind(wxEVT_LEFT_UP, &GUINode::OnLeftMouseUp, this);

	Bind(wxEVT_LEFT_DOWN, &GUINode::OnLeftMouseDown, this);
	Bind(wxEVT_LEFT_UP, &GUINode::OnLeftMouseUp, this);
	Bind(wxEVT_MOTION, &GUINode::OnMouseMotion, this);
	Bind(wxEVT_PAINT, &GUINode::OnPaint, this);
}

wxSize GUINode::DoGetBestSize() const
{
	return m_bestSize;
}

void GUINode::OnPaint(wxPaintEvent &event)
{
	wxPaintDC dc(this);
	wxGraphicsContext *gc = wxGraphicsContext::Create(dc);
	wxFont font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);

	int height = GetSize().GetHeight() - 1;
	int width = GetSize().GetWidth() - 1;
	int i = 0;
	if (gc)
	{
		// Draw the body
		gc->SetBrush(*wxRED_BRUSH);
		gc->SetPen(wxPen(*wxBLACK, 1));
		gc->DrawRoundedRectangle(0, 0, m_bestSize.GetWidth() - 1, m_bestSize.GetHeight() - 1, 10);

		gc->SetBrush(*wxBLUE_BRUSH);
		gc->SetFont(font, *wxBLACK);
		i = 0;
		// Draw the inputs
		for (InputParam p : m_node.GetInputs()) {
			gc->DrawEllipse(10, (i+0.5f)*height / m_maxParamsPerColumn, 25, 25);
			gc->DrawText(p.GetName(), 50, (i + 0.5f)*height / m_maxParamsPerColumn);
			i++;
		}
		i = 0;
		// Draw the outputs
		for (OutputParam p : m_node.GetOutputs()) {
			gc->DrawEllipse(width-50, (i+0.5f)*height / m_maxParamsPerColumn, 25, 25);
			gc->DrawText(p.GetName(), width-100, (i + 0.5f)*height / m_maxParamsPerColumn);
			i++;
		}

		delete gc;
	}

	event.Skip();
}

void GUINode::OnLeftMouseDown(wxMouseEvent& event)
{
	m_isDragging = true;
	m_firstDraggingPoint = ScreenToClient(ClientToScreen(event.GetPosition()));
}

void GUINode::OnLeftMouseUp(wxMouseEvent& event)
{
	m_isDragging = false;
}

void GUINode::OnMouseMotion(wxMouseEvent& event)
{
	if (m_isDragging && event.LeftIsDown())
		SetPosition(m_parent->ScreenToClient(ClientToScreen(event.GetPosition())) - m_firstDraggingPoint);
}<|endoftext|>


<commit_before>/**************************************************************************
 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

/* $Id:  */

//_________________________________________________________________________
//  A singleton that retrieves objets from an array stored in a Tree on a disk file
//    1. AliPHOSDigit from TreeD
//
//*-- Author: Yves Schutz (SUBATECH)
//////////////////////////////////////////////////////////////////////////////

// --- ROOT system ---

// --- Standard library ---

// --- AliRoot header files ---

#include "AliPHOSIndexToObject.h"

ClassImp(AliPHOSIndexToObject)

  AliPHOSIndexToObject * AliPHOSIndexToObject::fgObjGetter = 0 ;

//____________________________________________________________________________
AliPHOSIndexToObject::AliPHOSIndexToObject(AliPHOS * det)
{
  // ctor called once to initialize the detector in use

  fDetector = det ;
}

//____________________________________________________________________________
AliPHOSIndexToObject * AliPHOSIndexToObject::GetInstance()
{
  // Returns the pointer of the unique instance already defined

  AliPHOSIndexToObject * rv = 0 ;
  if ( fgObjGetter )
    rv = fgObjGetter ;
  else
    cout << "AliPHOSIndexToObject::GetInstance ERROR: not yet initialized" << endl ;

  return rv ;
}

//____________________________________________________________________________
AliPHOSIndexToObject * AliPHOSIndexToObject::GetInstance(AliPHOS * det)
{
  // Creates and returns the pointer of the unique instance
  // Must be called only when the environment has changed (a new event for exemple)

  if ( fgObjGetter )      // delete it if already exists
    delete fgObjGetter ;

  fgObjGetter = new AliPHOSIndexToObject(det) ;

  return fgObjGetter ;

}

//____________________________________________________________________________
AliPHOSDigit * AliPHOSIndexToObject::GimeDigit(Int_t index)
{
  // returns the object AliPHOSDigit stored at array position index in TreeD

  AliPHOSDigit * rv = 0 ;

  if ( index >= fDetector->Digits()->GetEntries() )
    cout << "AliPHOSIndexToObject::GimeDigit: index " << index << " larger than available entries "
	 <<  fDetector->Digits()->GetEntries() << endl ;
  else if ( index != -1)
    rv =  (AliPHOSDigit *) (fDetector->Digits()->At(index) ) ;

  return rv ;

}
//____________________________________________________________________________
TParticle * AliPHOSIndexToObject::GimePrimaryParticle(Int_t index)
{
  // returns the object TParticle stored at array position index in TreeK

  TParticle * rv = 0 ;

  if ( index >= gAlice->Particles()->GetEntries() )
    cout << "AliPHOSIndexToObject::GimePrimaryParticles: index " << index << " larger than available entries "
	 <<  gAlice->Particles()->GetEntries() << endl ;
  else
    rv =  (TParticle *) (gAlice->Particles()->At(index) ) ;

  return rv ;

}

//____________________________________________________________________________
AliPHOSRecParticle * AliPHOSIndexToObject::GimeRecParticle(Int_t index)
{
  // returns the object AliPHOSRecParticle stored at array position index in TreeR/PHOSRP
  // this one takes more work because the detetor object and the objects in TreeR are not saved at the same time
  // therefore the links are lost

  AliPHOSRecParticle * rv = 0 ;

  AliPHOSRecParticle::RecParticlesList * rplist = fDetector->RecParticles() ;

  Int_t rpentries  = 0 ;

  if (rplist)
    rpentries = rplist->GetEntries() ;

  fReconstruct = gAlice->TreeR() ;

  if (!rpentries) {
    fReconstruct->SetBranchAddress( "PHOSRP", &rplist ) ;
    fReconstruct->GetEvent(0) ;
    rpentries = rplist->GetEntries() ;
  }

  if ( index >= rpentries )  // ERROR
    cout << "AliPHOSIndexToObject::GimeRecParticle: index " << index << " larger than available entries "
	   <<  rpentries << endl ;
  else
    rv =  (AliPHOSRecParticle *) (fDetector->RecParticles()->At(index) ) ;

  return rv ;

}

//____________________________________________________________________________
AliRecPoint * AliPHOSIndexToObject::GimeRecPoint(Int_t index, TString type)
{
  // returns the object AliPHOSRecPoint stored at array position index in TreeR/PHOSEmcRP or TreeR/PHOSPpsdRP
  // this one takes more work because the detetor object and the objects in TreeR are not saved at the same time
  // therefore the links are lost

  AliPHOSRecPoint * rv = 0 ;

  AliPHOSRecPoint::RecPointsList * emclist = fDetector->EmcRecPoints() ;
  AliPHOSRecPoint::RecPointsList * ppsdlist = fDetector->PpsdRecPoints() ;

  Int_t emcentries  = 0 ;
  Int_t ppsdentries = 0 ;

  if (emclist)
    emcentries = emclist->GetEntries() ;

  if (ppsdlist)
    ppsdentries= ppsdlist->GetEntries() ;

  fReconstruct = gAlice->TreeR() ;

  if (!emcentries || !ppsdentries) {
    fReconstruct->SetBranchAddress("PHOSEmcRP",&emclist);
    fReconstruct->SetBranchAddress("PHOSPpsdRP",&ppsdlist);
    fReconstruct->GetEvent(0) ;
    emcentries = emclist->GetEntries() ;
    ppsdentries= ppsdlist->GetEntries() ;
  }

  if ( type == "emc" ) {
    if ( index >= emcentries )
      cout << "AliPHOSIndexToObject::GimeRecPoint emc: index " << index << " larger than available entries "
	   <<  emcentries << endl ;
    else
      rv =  (AliPHOSEmcRecPoint *) ( emclist->At(index) ) ;
  }
  else if ( type == "ppsd" ) {
    if ( index >= ppsdentries )
      cout << "AliPHOSIndexToObject::GimeRecPoint ppsd: index " << index << " larger than available entries "
	   <<  ppsdentries << endl ;
    else if (index != -1)
      rv =  (AliPHOSPpsdRecPoint *) (ppsdlist->At(index) ) ;
  } else
    cout << "AliPHOSIndexToObject::GimeRecPoint: " << type << " is an unknown type " << endl
	 << " valid types are : emc " << endl
	 << "                   ppsd " << endl ;

  return rv ;

}

//____________________________________________________________________________
AliPHOSTrackSegment * AliPHOSIndexToObject::GimeTrackSegment(Int_t index)
{
  // returns the object AliPHOSTrackSegment stored at array position index in TreeR/PHOSTS
  // this one takes more work because the detetor object and the objects in TreeR are not saved at the same time
  // therefore the links are lost

  AliPHOSTrackSegment * rv = 0 ;

  AliPHOSTrackSegment::TrackSegmentsList * tslist = fDetector->TrackSegments() ;

  Int_t tsentries  = 0 ;

  if (tslist)
    tsentries = tslist->GetEntries() ;

  fReconstruct = gAlice->TreeR() ;

  if (!tsentries) {
    fReconstruct->SetBranchAddress( "PHOSTS", &tslist ) ;
    fReconstruct->GetEvent(0) ;
    tsentries = tslist->GetEntries() ;
  }

  if ( index >= tsentries )  // ERROR
      cout << "AliPHOSIndexToObject::GimeTrackSegment: index " << index << " larger than available entries "
	   <<  tsentries << endl ;
  else
    rv =  (AliPHOSTrackSegment *) (tslist->At(index) ) ;

  return rv ;

}
<commit_msg>Solved a weird problem. It was calling SetAdress where it should never had done so. This is the problem that screwed up the reconstruction when trying to fill TreeR.<commit_after>/**************************************************************************
 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

/* $Id:  */

//_________________________________________________________________________
//  A singleton that retrieves objets from an array stored in a Tree on a disk file
//    1. AliPHOSDigit from TreeD
//
//*-- Author: Yves Schutz (SUBATECH)
//////////////////////////////////////////////////////////////////////////////

// --- ROOT system ---

// --- Standard library ---

// --- AliRoot header files ---

#include "AliPHOSIndexToObject.h"

ClassImp(AliPHOSIndexToObject)

  AliPHOSIndexToObject * AliPHOSIndexToObject::fgObjGetter = 0 ;

//____________________________________________________________________________
AliPHOSIndexToObject::AliPHOSIndexToObject(AliPHOS * det)
{
  // ctor called once to initialize the detector in use

  fDetector = det ;
}

//____________________________________________________________________________
AliPHOSIndexToObject * AliPHOSIndexToObject::GetInstance()
{
  // Returns the pointer of the unique instance already defined

  AliPHOSIndexToObject * rv = 0 ;
  if ( fgObjGetter )
    rv = fgObjGetter ;
  else
    cout << "AliPHOSIndexToObject::GetInstance ERROR: not yet initialized" << endl ;

  return rv ;
}

//____________________________________________________________________________
AliPHOSIndexToObject * AliPHOSIndexToObject::GetInstance(AliPHOS * det)
{
  // Creates and returns the pointer of the unique instance
  // Must be called only when the environment has changed (a new event for exemple)

  if ( fgObjGetter )      // delete it if already exists
    delete fgObjGetter ;

  fgObjGetter = new AliPHOSIndexToObject(det) ;

  return fgObjGetter ;

}

//____________________________________________________________________________
AliPHOSDigit * AliPHOSIndexToObject::GimeDigit(Int_t index)
{
  // returns the object AliPHOSDigit stored at array position index in TreeD

  AliPHOSDigit * rv = 0 ;

  if ( index >= fDetector->Digits()->GetEntries() )
    cout << "AliPHOSIndexToObject::GimeDigit: index " << index << " larger than available entries "
	 <<  fDetector->Digits()->GetEntries() << endl ;
  else if ( index != -1)
    rv =  (AliPHOSDigit *) (fDetector->Digits()->At(index) ) ;

  return rv ;

}
//____________________________________________________________________________
TParticle * AliPHOSIndexToObject::GimePrimaryParticle(Int_t index)
{
  // returns the object TParticle stored at array position index in TreeK

  TParticle * rv = 0 ;

  if ( index >= gAlice->Particles()->GetEntries() )
    cout << "AliPHOSIndexToObject::GimePrimaryParticles: index " << index << " larger than available entries "
	 <<  gAlice->Particles()->GetEntries() << endl ;
  else
    rv =  (TParticle *) (gAlice->Particles()->At(index) ) ;

  return rv ;

}

//____________________________________________________________________________
AliPHOSRecParticle * AliPHOSIndexToObject::GimeRecParticle(Int_t index)
{
  // returns the object AliPHOSRecParticle stored at array position index in TreeR/PHOSRP
  // this one takes more work because the detetor object and the objects in TreeR are not saved at the same time
  // therefore the links are lost

  AliPHOSRecParticle * rv = 0 ;

  AliPHOSRecParticle::RecParticlesList * rplist = fDetector->RecParticles() ;

  Int_t rpentries  = 0 ;

  if (rplist)
    rpentries = rplist->GetEntries() ;

  fReconstruct = gAlice->TreeR() ;

  if (!rpentries) {
    fReconstruct->SetBranchAddress( "PHOSRP", &rplist ) ;
    fReconstruct->GetEvent(0) ;
    rpentries = rplist->GetEntries() ;
  }

  if ( index >= rpentries )  // ERROR
    cout << "AliPHOSIndexToObject::GimeRecParticle: index " << index << " larger than available entries "
	   <<  rpentries << endl ;
  else
    rv =  (AliPHOSRecParticle *) (fDetector->RecParticles()->At(index) ) ;

  return rv ;

}

//____________________________________________________________________________
AliRecPoint * AliPHOSIndexToObject::GimeRecPoint(Int_t index, TString type)
{
  // returns the object AliPHOSRecPoint stored at array position index in TreeR/PHOSEmcRP or TreeR/PHOSPpsdRP
  // this one takes more work because the detetor object and the objects in TreeR are not saved at the same time
  // therefore the links are lost

  AliPHOSRecPoint * rv = 0 ;

  AliPHOSRecPoint::RecPointsList * emclist = fDetector->EmcRecPoints() ;
  AliPHOSRecPoint::RecPointsList * ppsdlist = fDetector->PpsdRecPoints() ;

  Int_t emcentries  = 0 ;
  Int_t ppsdentries = 0 ;

  if (emclist)
    emcentries = emclist->GetEntries() ;

  if (ppsdlist)
    ppsdentries= ppsdlist->GetEntries() ;

  fReconstruct = gAlice->TreeR() ;

  if (!emcentries && !ppsdentries) {
    fReconstruct->SetBranchAddress("PHOSEmcRP",&emclist);
    fReconstruct->SetBranchAddress("PHOSPpsdRP",&ppsdlist);
    fReconstruct->GetEvent(0) ;
    emcentries = emclist->GetEntries() ;
    ppsdentries= ppsdlist->GetEntries() ;
  }

  if ( type == "emc" ) {
    if ( index >= emcentries )
      cout << "AliPHOSIndexToObject::GimeRecPoint emc: index " << index << " larger than available entries "
	   <<  emcentries << endl ;
    else
      rv =  (AliPHOSEmcRecPoint *) ( emclist->At(index) ) ;
  }
  else if ( type == "ppsd" ) {
    if ( index >= ppsdentries )
      cout << "AliPHOSIndexToObject::GimeRecPoint ppsd: index " << index << " larger than available entries "
	   <<  ppsdentries << endl ;
    else if (index != -1)
      rv =  (AliPHOSPpsdRecPoint *) (ppsdlist->At(index) ) ;
  } else
    cout << "AliPHOSIndexToObject::GimeRecPoint: " << type << " is an unknown type " << endl
	 << " valid types are : emc " << endl
	 << "                   ppsd " << endl ;

  return rv ;

}

//____________________________________________________________________________
AliPHOSTrackSegment * AliPHOSIndexToObject::GimeTrackSegment(Int_t index)
{
  // returns the object AliPHOSTrackSegment stored at array position index in TreeR/PHOSTS
  // this one takes more work because the detetor object and the objects in TreeR are not saved at the same time
  // therefore the links are lost

  AliPHOSTrackSegment * rv = 0 ;

  AliPHOSTrackSegment::TrackSegmentsList * tslist = fDetector->TrackSegments() ;

  Int_t tsentries  = 0 ;

  if (tslist)
    tsentries = tslist->GetEntries() ;

  fReconstruct = gAlice->TreeR() ;

  if (!tsentries) {
    fReconstruct->SetBranchAddress( "PHOSTS", &tslist ) ;
    fReconstruct->GetEvent(0) ;
    tsentries = tslist->GetEntries() ;
  }

  if ( index >= tsentries )  // ERROR
      cout << "AliPHOSIndexToObject::GimeTrackSegment: index " << index << " larger than available entries "
	   <<  tsentries << endl ;
  else
    rv =  (AliPHOSTrackSegment *) (tslist->At(index) ) ;

  return rv ;

}
<|endoftext|>


<commit_before>AliAnalysisTaskParticleCorrelation *AddTaskPartCorr(TString data, TString calorimeter, Bool_t kUseKinematics = kFALSE, Bool_t kPrintSettings = kFALSE)
{
  // Creates a PartCorr task, configures it and adds it to the analysis manager.

  // Get the pointer to the existing analysis manager via the static access method.
  //==============================================================================
  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
  if (!mgr) {
    ::Error("AddTaskPartCorr", "No analysis manager to connect to.");
    return NULL;
  }

  // Check the analysis type using the event handlers connected to the analysis manager.
  //==============================================================================
  if (!mgr->GetInputEventHandler()) {
    ::Error("AddTaskPartCorr", "This task requires an input event handler");
    return NULL;
  }
   TString inputDataType = mgr->GetInputEventHandler()->GetDataType(); // can be "ESD" or "AOD"
   //cout<<"DATA TYPE :: "<<inputDataType<<endl;
   // inputDataType: data managed by the input handler
   // data: can be same as one managed by input handler, or the output AOD created by the filter. By default use AOD

   // Configure analysis
   //===========================================================================

  //Reader
  AliCaloTrackReader * reader = 0x0;
  if(data=="AOD") reader = new AliCaloTrackAODReader();
  else if(data=="ESD") reader = new AliCaloTrackESDReader();
  else if(data=="MC" && dataType == "ESD") reader = new AliCaloTrackMCReader();
  reader->SetDebug(-1);//10 for lots of messages
  if(calorimeter == "EMCAL") reader->SwitchOnEMCALCells();
  if(calorimeter == "PHOS")  reader->SwitchOnPHOSCells();
  if(kUseKinematics){
	if(inputDataType == "ESD"){
		reader->SwitchOnStack();
		reader->SwitchOffAODMCParticles();
	}
	else if(inputDataType == "AOD"){
		reader->SwitchOffStack();
		reader->SwitchOnAODMCParticles();
	}
  }

  //Min particle pT
  reader->SetEMCALPtMin(0.2);
  reader->SetPHOSPtMin(0.2);
  reader->SetCTSPtMin(0.2);
  if(kPrintSettings) reader->Print("");

  // ##### Analysis algorithm settings ####

  // --------------------
  // --- Pi0 Analysis ---
  // --------------------

  AliCaloPID * pid = new AliCaloPID();
  pid->SetDispersionCut(1.5);
  pid->SetTOFCut(5.e-9);
  pid->SetDebug(-1);
  if(kPrintSettings) pid->Print("");

  AliFidutialCut * fidCut = new AliFidutialCut();
  fidCut->DoCTSFidutialCut(kFALSE) ;
  fidCut->DoEMCALFidutialCut(kTRUE) ;
  fidCut->DoPHOSFidutialCut(kTRUE) ;

  AliAnaCalorimeterQA *qa = new AliAnaCalorimeterQA();
  qa->SetDebug(-1); //10 for lots of messages
  qa->SetCalorimeter(calorimeter);
  if(kUseKinematics && inputDataType!="AOD") qa->SwitchOnDataMC() ;//Access MC stack and fill more histograms, AOD MC not implemented yet.
  else  qa->SwitchOffDataMC() ;
  qa->AddToHistogramsName(Form("AnaCaloQA_%s",calorimeter.Data()));
  qa->SetFidutialCut(fidCut);
  qa->SwitchOnFidutialCut();
  if(kPrintSettings) qa->Print("");

  AliFidutialCut * fidCut1stYear = new AliFidutialCut();
  fidCut1stYear->DoCTSFidutialCut(kFALSE) ;
  fidCut1stYear->DoEMCALFidutialCut(kTRUE) ;
  fidCut1stYear->DoPHOSFidutialCut(kTRUE) ;
  fidCut1stYear->SetSimpleEMCALFidutialCut(0.7,80.,120.);
  fidCut1stYear->SetSimplePHOSFidutialCut(0.12,260.,320.);

  AliAnaPhoton *anaphoton1 = new AliAnaPhoton();
  anaphoton1->SetDebug(-1); //10 for lots of messages
  //anaphoton->SetMinPt(0.5);
  anaphoton1->SetMinDistanceToBadChannel(2, 4, 5);
  anaphoton1->SetCaloPID(pid);
  anaphoton1->SetCalorimeter(calorimeter);
  if(kUseKinematics) anaphoton1->SwitchOnDataMC() ;//Access MC stack and fill more histograms
  else  anaphoton1->SwitchOffDataMC() ;
  anaphoton1->SwitchOffCaloPID();
  anaphoton1->SwitchOffCaloPIDRecalculation(); //recommended for EMCAL
  anaphoton1->SwitchOnFidutialCut();
  anaphoton1->SetFidutialCut(fidCut1stYear);
  anaphoton1->SetOutputAODName(Form("PhotonsForIM%s",calorimeter.Data()));
  if(kPrintSettings) anaphoton1->Print("");

  AliAnaPi0 *anapi0 = new AliAnaPi0();
  anapi0->SetDebug(-1);//10 for lots of messages
  anapi0->SetInputAODName(Form("PhotonsForIM%s",calorimeter.Data()));
  anapi0->SetCaloPID(pid);
  anapi0->SetCalorimeter(calorimeter);
  anapi0->SwitchOnFidutialCut();
  anapi0->SwitchOffDataMC() ;//Access MC stack and fill more histograms
  if(kPrintSettings) anapi0->Print("");

  // -------------------------------------------------
  // --- Photon Isolation and Correlation Analysis ---
  // -------------------------------------------------

  AliAnaPhoton *anaphoton2 = new AliAnaPhoton();
  anaphoton2->SetDebug(-1); //10 for lots of messages
  anaphoton2->SetMinPt(5);
  anaphoton2->SetCaloPID(pid);
  anaphoton2->SetCalorimeter(calorimeter);
  if(kUseKinematics) anaphoton2->SwitchOnDataMC() ;//Access MC stack and fill more histograms
  else  anaphoton2->SwitchOffDataMC() ;
  anaphoton2->SwitchOnCaloPID();
  if(calorimeter == "EMCAL") anaphoton2->SwitchOnCaloPIDRecalculation();
  anaphoton2->SwitchOffFidutialCut();
  anaphoton2->SetOutputAODName(Form("DirectPhotons%s",calorimeter.Data()));
  anaphoton2->SetOutputAODClassName("AliAODPWG4ParticleCorrelation");
  anaphoton2->AddToHistogramsName("AnaPhotonCorr_");
  if(kPrintSettings) anaphoton2->Print("");
  // ### Isolation analysis ###

  AliIsolationCut * ic = new AliIsolationCut();
  ic->SetConeSize(0.5);
  ic->SetPtThreshold(1.);
  ic->SetICMethod(AliIsolationCut::kPtThresIC);
  if(kPrintSettings) ic->Print("");

  AliAnaParticleIsolation *anaisol = new AliAnaParticleIsolation();
  anaisol->SetDebug(-1);
  //anaisol->SetMinPt(5);
  anaisol->SetInputAODName(Form("DirectPhotons%s",calorimeter.Data()));
  anaisol->SetCalorimeter(calorimeter);
  if(kUseKinematics) anaisol->SwitchOnDataMC() ;//Access MC stack and fill more histograms
  else  anaisol->SwitchOffDataMC() ;
  //Select clusters with no pair, if both clusters with pi0 mass
  anaisol->SwitchOffInvariantMass();
  //anaisol->SetNeutralMesonSelection(nms);
  //Do isolation cut
  anaisol->SetIsolationCut(ic);
  //Do or not do isolation with previously produced AODs.
  //No effect if use of SwitchOnSeveralIsolation()
  anaisol->SwitchOffReIsolation();
  //Multiple IC
  anaisol->SwitchOffSeveralIsolation() ;
  if(kPrintSettings) anaisol->Print("");

  // ### Correlation with Jet Finder AOD output
  AliAnaParticleJetFinderCorrelation *anacorrjet = new AliAnaParticleJetFinderCorrelation();
  anacorrjet->SetInputAODName(Form("DirectPhotons%s",calorimeter.Data()));
  anacorrjet->SwitchOffFidutialCut();
  anacorrjet->SetDebug(-1);
  anacorrjet->SetConeSize(1);
  anacorrjet->SelectIsolated(kTRUE); // do correlation with isolated photons
  anacorrjet->SetPtThresholdInCone(0.2);
  anacorrjet->SetDeltaPhiCutRange(0.5,5.5);//Mostly Open Cuts
  anacorrjet->SetRatioCutRange(0.01,3); //Mostly Open Cuts
  anacorrjet->UseJetRefTracks(kFALSE); //Not working now
  if(kPrintSettings) anacorrjet->Print("");

  // ### Correlation with hadrons
  AliAnaParticleHadronCorrelation *anacorrhadron = new AliAnaParticleHadronCorrelation();
  anacorrhadron->SetInputAODName(Form("DirectPhotons%s",calorimeter.Data()));
  anacorrhadron->SetOutputAODName(Form("CorrelatedPi0s%s",calorimeter.Data()));
  anacorrhadron->SetOutputAODClassName("AliAODPWG4ParticleCorrelation");
  anacorrhadron->SetDebug(-1);
  anacorrhadron->SwitchOffCaloPID();
  anacorrhadron->SwitchOffFidutialCut();
  anacorrhadron->SetPtCutRange(1,100);
  anacorrhadron->SetDeltaPhiCutRange(1.5,4.5);
  anacorrhadron->SelectIsolated(kTRUE); // do correlation with isolated photons
  if(calorimeter=="PHOS"){
    //Correlate with particles in EMCAL
    anacorrhadron->SwitchOnCaloPID();
    anacorrhadron->SwitchOnCaloPIDRecalculation(); //recommended for EMCAL
  }
  if(kPrintSettings) anacorrhadron->Print("");

  // #### Configure Maker ####
  AliAnaPartCorrMaker * maker = new AliAnaPartCorrMaker();
  maker->SetReader(reader);//pointer to reader
  maker->AddAnalysis(qa,0);
  maker->AddAnalysis(anaphoton1,1);
  maker->AddAnalysis(anapi0,2);
  maker->AddAnalysis(anaphoton2,3);
  maker->AddAnalysis(anaisol,4);
  maker->AddAnalysis(anacorrjet,5);
  maker->AddAnalysis(anacorrhadron,6);
  maker->SetAnaDebug(-1)  ;
  maker->SwitchOnHistogramsMaker()  ;
  maker->SwitchOnAODsMaker()  ;
  if(kPrintSettings) maker->Print("");

  printf("======================== \n");
  printf(" End Configuration of PartCorr analysis with detector %s \n",calorimeter.Data());
  printf("======================== \n");

   // Create task
   //===========================================================================
  AliAnalysisTaskParticleCorrelation * task = new AliAnalysisTaskParticleCorrelation (Form("PartCorr%s",calorimeter.Data()));
  task->SetConfigFileName(""); //Don't configure the analysis via configuration file.
  //task->SetDebugLevel(-1);
  task->SetAnalysisMaker(maker);
  mgr->AddTask(task);

  char name[128];
  sprintf(name,"PartCorr_%s",calorimeter.Data());
cout<<"Name of task "<<name<<endl;
  AliAnalysisDataContainer *cout_pc = mgr->CreateContainer(Form(name),TList::Class(),
							   AliAnalysisManager::kOutputContainer, Form("PartCorr_%s.root",calorimeter.Data()));

  // Create ONLY the output containers for the data produced by the task.
  // Get and connect other common input/output containers via the manager as below
  //==============================================================================
  mgr->ConnectInput  (task, 0, mgr->GetCommonInputContainer());
  // AOD output slot will be used in a different way in future
  mgr->ConnectOutput (task, 0, mgr->GetCommonOutputContainer());
  mgr->ConnectOutput (task, 1, cout_pc);

  return task;
}

<commit_msg>folders to keep the wagons output in the common analysis file defined, do not clear cluster/track lists+<commit_after>AliAnalysisTaskParticleCorrelation *AddTaskPartCorr(TString data, TString calorimeter, Bool_t kUseKinematics = kFALSE, Bool_t kPrintSettings = kFALSE)
{
  // Creates a PartCorr task, configures it and adds it to the analysis manager.

  // Get the pointer to the existing analysis manager via the static access method.
  //==============================================================================
  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
  if (!mgr) {
    ::Error("AddTaskPartCorr", "No analysis manager to connect to.");
    return NULL;
  }

  // Check the analysis type using the event handlers connected to the analysis manager.
  //==============================================================================
  if (!mgr->GetInputEventHandler()) {
    ::Error("AddTaskPartCorr", "This task requires an input event handler");
    return NULL;
  }
   TString inputDataType = mgr->GetInputEventHandler()->GetDataType(); // can be "ESD" or "AOD"
   //cout<<"DATA TYPE :: "<<inputDataType<<endl;
   // inputDataType: data managed by the input handler
   // data: can be same as one managed by input handler, or the output AOD created by the filter. By default use AOD

   // Configure analysis
   //===========================================================================

  //Reader
  AliCaloTrackReader * reader = 0x0;
  if(data=="AOD") reader = new AliCaloTrackAODReader();
  else if(data=="ESD") reader = new AliCaloTrackESDReader();
  else if(data=="MC" && dataType == "ESD") reader = new AliCaloTrackMCReader();
  reader->SetDebug(-1);//10 for lots of messages
  if(calorimeter == "EMCAL") reader->SwitchOnEMCALCells();
  if(calorimeter == "PHOS")  reader->SwitchOnPHOSCells();
  if(kUseKinematics){
	if(inputDataType == "ESD"){
		reader->SwitchOnStack();
		reader->SwitchOffAODMCParticles();
	}
	else if(inputDataType == "AOD"){
		reader->SwitchOffStack();
		reader->SwitchOnAODMCParticles();
	}
  }

  //Min particle pT
  reader->SetEMCALPtMin(0.2);
  reader->SetPHOSPtMin(0.2);
  reader->SetCTSPtMin(0.2);
  if(kPrintSettings) reader->Print("");

  //Needed line, do not clear standard output AODs, we are not writing there
  reader->SwitchOnWriteStdAOD();

  // ##### Analysis algorithm settings ####

  // --------------------
  // --- Pi0 Analysis ---
  // --------------------

  AliCaloPID * pid = new AliCaloPID();
  pid->SetDispersionCut(1.5);
  pid->SetTOFCut(5.e-9);
  pid->SetDebug(-1);
  if(kPrintSettings) pid->Print("");

  AliFidutialCut * fidCut = new AliFidutialCut();
  fidCut->DoCTSFidutialCut(kFALSE) ;
  fidCut->DoEMCALFidutialCut(kTRUE) ;
  fidCut->DoPHOSFidutialCut(kTRUE) ;

  AliAnaCalorimeterQA *qa = new AliAnaCalorimeterQA();
  qa->SetDebug(-1); //10 for lots of messages
  qa->SetCalorimeter(calorimeter);
  if(kUseKinematics && inputDataType!="AOD") qa->SwitchOnDataMC() ;//Access MC stack and fill more histograms, AOD MC not implemented yet.
  else  qa->SwitchOffDataMC() ;
  //qa->AddToHistogramsName(Form("AnaCaloQA_%s",calorimeter.Data()));
  qa->AddToHistogramsName("AnaCaloQA_");
  qa->SetFidutialCut(fidCut);
  qa->SwitchOnFidutialCut();
  if(kPrintSettings) qa->Print("");

  AliFidutialCut * fidCut1stYear = new AliFidutialCut();
  fidCut1stYear->DoCTSFidutialCut(kFALSE) ;
  fidCut1stYear->DoEMCALFidutialCut(kTRUE) ;
  fidCut1stYear->DoPHOSFidutialCut(kTRUE) ;
  fidCut1stYear->SetSimpleEMCALFidutialCut(0.7,80.,120.);
  fidCut1stYear->SetSimplePHOSFidutialCut(0.12,260.,320.);

  AliAnaPhoton *anaphoton1 = new AliAnaPhoton();
  anaphoton1->SetDebug(-1); //10 for lots of messages
  //anaphoton->SetMinPt(0.5);
  anaphoton1->SetMinDistanceToBadChannel(2, 4, 5);
  anaphoton1->SetCaloPID(pid);
  anaphoton1->SetCalorimeter(calorimeter);
  if(kUseKinematics) anaphoton1->SwitchOnDataMC() ;//Access MC stack and fill more histograms
  else  anaphoton1->SwitchOffDataMC() ;
  anaphoton1->SwitchOffCaloPID();
  anaphoton1->SwitchOffCaloPIDRecalculation(); //recommended for EMCAL
  anaphoton1->SwitchOnFidutialCut();
  anaphoton1->SetFidutialCut(fidCut1stYear);
  anaphoton1->SetOutputAODName(Form("PhotonsForIM%s",calorimeter.Data()));
  if(kPrintSettings) anaphoton1->Print("");

  AliAnaPi0 *anapi0 = new AliAnaPi0();
  anapi0->SetDebug(-1);//10 for lots of messages
  anapi0->SetInputAODName(Form("PhotonsForIM%s",calorimeter.Data()));
  anapi0->SetCaloPID(pid);
  anapi0->SetCalorimeter(calorimeter);
  anapi0->SwitchOnFidutialCut();
  anapi0->SwitchOffDataMC() ;//Access MC stack and fill more histograms
  if(kPrintSettings) anapi0->Print("");

  // -------------------------------------------------
  // --- Photon Isolation and Correlation Analysis ---
  // -------------------------------------------------

  AliAnaPhoton *anaphoton2 = new AliAnaPhoton();
  anaphoton2->SetDebug(-1); //10 for lots of messages
  anaphoton2->SetMinPt(5);
  anaphoton2->SetCaloPID(pid);
  anaphoton2->SetCalorimeter(calorimeter);
  if(kUseKinematics) anaphoton2->SwitchOnDataMC() ;//Access MC stack and fill more histograms
  else  anaphoton2->SwitchOffDataMC() ;
  anaphoton2->SwitchOnCaloPID();
  if(calorimeter == "EMCAL") anaphoton2->SwitchOnCaloPIDRecalculation();
  anaphoton2->SwitchOffFidutialCut();
  anaphoton2->SetOutputAODName(Form("DirectPhotons%s",calorimeter.Data()));
  anaphoton2->SetOutputAODClassName("AliAODPWG4ParticleCorrelation");
  anaphoton2->AddToHistogramsName("AnaPhotonCorr_");
  if(kPrintSettings) anaphoton2->Print("");
  // ### Isolation analysis ###

  AliIsolationCut * ic = new AliIsolationCut();
  ic->SetConeSize(0.5);
  ic->SetPtThreshold(1.);
  ic->SetICMethod(AliIsolationCut::kPtThresIC);
  if(kPrintSettings) ic->Print("");

  AliAnaParticleIsolation *anaisol = new AliAnaParticleIsolation();
  anaisol->SetDebug(-1);
  //anaisol->SetMinPt(5);
  anaisol->SetInputAODName(Form("DirectPhotons%s",calorimeter.Data()));
  anaisol->SetCalorimeter(calorimeter);
  if(kUseKinematics) anaisol->SwitchOnDataMC() ;//Access MC stack and fill more histograms
  else  anaisol->SwitchOffDataMC() ;
  //Select clusters with no pair, if both clusters with pi0 mass
  anaisol->SwitchOffInvariantMass();
  //anaisol->SetNeutralMesonSelection(nms);
  //Do isolation cut
  anaisol->SetIsolationCut(ic);
  //Do or not do isolation with previously produced AODs.
  //No effect if use of SwitchOnSeveralIsolation()
  anaisol->SwitchOffReIsolation();
  //Multiple IC
  anaisol->SwitchOffSeveralIsolation() ;
  if(kPrintSettings) anaisol->Print("");

  // ### Correlation with Jet Finder AOD output
  AliAnaParticleJetFinderCorrelation *anacorrjet = new AliAnaParticleJetFinderCorrelation();
  anacorrjet->SetInputAODName(Form("DirectPhotons%s",calorimeter.Data()));
  anacorrjet->SwitchOffFidutialCut();
  anacorrjet->SetDebug(-1);
  anacorrjet->SetConeSize(1);
  anacorrjet->SelectIsolated(kTRUE); // do correlation with isolated photons
  anacorrjet->SetPtThresholdInCone(0.2);
  anacorrjet->SetDeltaPhiCutRange(0.5,5.5);//Mostly Open Cuts
  anacorrjet->SetRatioCutRange(0.01,3); //Mostly Open Cuts
  anacorrjet->UseJetRefTracks(kFALSE); //Not working now
  if(kPrintSettings) anacorrjet->Print("");

  // ### Correlation with hadrons
  AliAnaParticleHadronCorrelation *anacorrhadron = new AliAnaParticleHadronCorrelation();
  anacorrhadron->SetInputAODName(Form("DirectPhotons%s",calorimeter.Data()));
  anacorrhadron->SetOutputAODName(Form("CorrelatedPi0s%s",calorimeter.Data()));
  anacorrhadron->SetOutputAODClassName("AliAODPWG4ParticleCorrelation");
  anacorrhadron->SetDebug(-1);
  anacorrhadron->SwitchOffCaloPID();
  anacorrhadron->SwitchOffFidutialCut();
  anacorrhadron->SetPtCutRange(1,100);
  anacorrhadron->SetDeltaPhiCutRange(1.5,4.5);
  anacorrhadron->SelectIsolated(kTRUE); // do correlation with isolated photons
  if(calorimeter=="PHOS"){
    //Correlate with particles in EMCAL
    anacorrhadron->SwitchOnCaloPID();
    anacorrhadron->SwitchOnCaloPIDRecalculation(); //recommended for EMCAL
  }
  if(kPrintSettings) anacorrhadron->Print("");

  // #### Configure Maker ####
  AliAnaPartCorrMaker * maker = new AliAnaPartCorrMaker();
  maker->SetReader(reader);//pointer to reader
  maker->AddAnalysis(qa,0);
  maker->AddAnalysis(anaphoton1,1);
  maker->AddAnalysis(anapi0,2);
  maker->AddAnalysis(anaphoton2,3);
  maker->AddAnalysis(anaisol,4);
  maker->AddAnalysis(anacorrjet,5);
  maker->AddAnalysis(anacorrhadron,6);
  maker->SetAnaDebug(-1)  ;
  maker->SwitchOnHistogramsMaker()  ;
  maker->SwitchOnAODsMaker()  ;
  if(kPrintSettings) maker->Print("");

  printf("======================== \n");
  printf(" End Configuration of PartCorr analysis with detector %s \n",calorimeter.Data());
  printf("======================== \n");

   // Create task
   //===========================================================================
  AliAnalysisTaskParticleCorrelation * task = new AliAnalysisTaskParticleCorrelation (Form("PartCorr%s",calorimeter.Data()));
  task->SetConfigFileName(""); //Don't configure the analysis via configuration file.
  //task->SetDebugLevel(-1);
  task->SetAnalysisMaker(maker);
  mgr->AddTask(task);

  char name[128];
  sprintf(name,"PartCorr_%s",calorimeter.Data());
  cout<<"Name of task "<<name<<endl;
  //AliAnalysisDataContainer *cout_pc = mgr->CreateContainer(Form(name),TList::Class(),
  	//					   AliAnalysisManager::kOutputContainer, Form("PartCorr_%s.root",calorimeter.Data()));

  TString outputfile = AliAnalysisManager::GetCommonFileName();
  //  AliAnalysisDataContainer *cout_pc = mgr->CreateContainer(Form("PartCorr_%s",calorimeter.Data()),  TList::Class(), AliAnalysisManager::kOutputContainer, Form("%s:PartCorr_%s",outputfile.Data(),calorimeter.Data()));
  AliAnalysisDataContainer *cout_pc = mgr->CreateContainer(calorimeter.Data(), TList::Class(), AliAnalysisManager::kOutputContainer, Form("%s:PartCorr",outputfile.Data()));

  // Create ONLY the output containers for the data produced by the task.
  // Get and connect other common input/output containers via the manager as below
  //==============================================================================
  mgr->ConnectInput  (task, 0, mgr->GetCommonInputContainer());
  // AOD output slot will be used in a different way in future
  mgr->ConnectOutput (task, 0, mgr->GetCommonOutputContainer());
  mgr->ConnectOutput (task, 1, cout_pc);

  return task;
}

<|endoftext|>


<commit_before>#include "Win32Window.h"
#include "../core/Game.h"

#define PHOENIX_WIN32WINDOW_CLASS_NAME TEXT("PhoenixCoreWin32Window")
#define PHOENIX_WIN32WINDOW_TEXT TEXT("PHOENIX")

static LRESULT CALLBACK PhoenixWndProc(HWND windowHandle, UINT message, WPARAM wParam, LPARAM lParam);

//========================================================================================================

Win32Window::~Win32Window()
{
    DestroyWindow(windowHandle_);
}

//========================================================================================================

Win32Window *Win32Window::create(HINSTANCE instanceHandle)
{
    //Allocate the object
    Win32Window *window = new Win32Window;
    window->instanceHandle_ = instanceHandle;
    window->windowHandle_ = 0;

    //Create the "window class"
    WNDCLASSEX wndClass;
    memset(&wndClass, 0, sizeof(WNDCLASSEX));

    wndClass.cbSize = sizeof(WNDCLASSEX);
    wndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    wndClass.hCursor = LoadCursor(instanceHandle, IDC_ARROW);
    wndClass.hIcon = LoadIcon(instanceHandle, IDI_APPLICATION); //TODO: Change to real icon
    wndClass.hInstance = instanceHandle;
    wndClass.lpfnWndProc = PhoenixWndProc;
    wndClass.lpszClassName = PHOENIX_WIN32WINDOW_CLASS_NAME;
    wndClass.style = CS_HREDRAW | CS_VREDRAW;

    //Register the class
    if (!RegisterClassEx(&wndClass))
    {
        delete window;
        return 0;
    }

    //Create the Window
    window->windowHandle_ = CreateWindow(PHOENIX_WIN32WINDOW_CLASS_NAME, PHOENIX_WIN32WINDOW_TEXT, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 800, 600, NULL, NULL, instanceHandle, window);

    //Show it
    ShowWindow(window->windowHandle_, SW_SHOWDEFAULT);
    UpdateWindow(window->windowHandle_);

    return window;
}

//========================================================================================================

LRESULT CALLBACK PhoenixWndProc(HWND windowHandle, UINT message, WPARAM wParam, LPARAM lParam)
{
    Win32Window *window = (Win32Window*)GetWindowLongPtr(windowHandle, GWLP_USERDATA);

    switch (message)
    {
    case WM_CREATE:
        SetWindowLongPtr(windowHandle, GWLP_USERDATA, lParam);
        break;

    case WM_DESTROY:
        PostQuitMessage(0);
        break;

    case WM_ACTIVATE:
        if (LOWORD(wParam) != 0)
        {
            Game::IsForegroundApp = true;
            Game::Events->publishEvent(EVID_SWITCH_TO_FOREGROUND, 0);
        }
        else
        {
            Game::IsForegroundApp = false;
            Game::Events->publishEvent(EVID_SWITCH_TO_BACKGROUND, 0);
        }
        break;
    }

    return DefWindowProc(windowHandle, message, wParam, lParam);
}
<commit_msg>Changed window background to be black<commit_after>#include "Win32Window.h"
#include "../core/Game.h"

#define PHOENIX_WIN32WINDOW_CLASS_NAME TEXT("PhoenixCoreWin32Window")
#define PHOENIX_WIN32WINDOW_TEXT TEXT("PHOENIX")

static LRESULT CALLBACK PhoenixWndProc(HWND windowHandle, UINT message, WPARAM wParam, LPARAM lParam);

//========================================================================================================

Win32Window::~Win32Window()
{
    DestroyWindow(windowHandle_);
}

//========================================================================================================

Win32Window *Win32Window::create(HINSTANCE instanceHandle)
{
    //Allocate the object
    Win32Window *window = new Win32Window;
    window->instanceHandle_ = instanceHandle;
    window->windowHandle_ = 0;

    //Create the "window class"
    WNDCLASSEX wndClass;
    memset(&wndClass, 0, sizeof(WNDCLASSEX));

    wndClass.cbSize = sizeof(WNDCLASSEX);
    wndClass.hbrBackground = (HBRUSH)(COLOR_WINDOWTEXT + 1);
    wndClass.hCursor = LoadCursor(instanceHandle, IDC_ARROW);
    wndClass.hIcon = LoadIcon(instanceHandle, IDI_APPLICATION); //TODO: Change to real icon
    wndClass.hInstance = instanceHandle;
    wndClass.lpfnWndProc = PhoenixWndProc;
    wndClass.lpszClassName = PHOENIX_WIN32WINDOW_CLASS_NAME;
    wndClass.style = CS_HREDRAW | CS_VREDRAW;

    //Register the class
    if (!RegisterClassEx(&wndClass))
    {
        delete window;
        return 0;
    }

    //Create the Window
    window->windowHandle_ = CreateWindow(PHOENIX_WIN32WINDOW_CLASS_NAME, PHOENIX_WIN32WINDOW_TEXT, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 800, 600, NULL, NULL, instanceHandle, window);

    //Show it
    ShowWindow(window->windowHandle_, SW_SHOWDEFAULT);
    UpdateWindow(window->windowHandle_);

    return window;
}

//========================================================================================================

LRESULT CALLBACK PhoenixWndProc(HWND windowHandle, UINT message, WPARAM wParam, LPARAM lParam)
{
    Win32Window *window = (Win32Window*)GetWindowLongPtr(windowHandle, GWLP_USERDATA);

    switch (message)
    {
    case WM_CREATE:
        SetWindowLongPtr(windowHandle, GWLP_USERDATA, lParam);
        break;

    case WM_DESTROY:
        PostQuitMessage(0);
        break;

    case WM_ACTIVATE:
        if (LOWORD(wParam) != 0)
        {
            Game::IsForegroundApp = true;
            Game::Events->publishEvent(EVID_SWITCH_TO_FOREGROUND, 0);
        }
        else
        {
            Game::IsForegroundApp = false;
            Game::Events->publishEvent(EVID_SWITCH_TO_BACKGROUND, 0);
        }
        break;
    }

    return DefWindowProc(windowHandle, message, wParam, lParam);
}
<|endoftext|>


<commit_before>#include "stdafx.h"

#include "ImageInfo.h"

#include "PixelUtil.h"

#define min(a, b) (((a) < (b)) ? (a) : (b))
#define max(a, b) (((a) < (b)) ? (b) : (a))

namespace mray{
namespace video{

ImageInfo::ImageInfo():format(EPixel_LUMINANCE8),
		imageData(0),imageDataSize(0)
{
	autoDel=true;
	tmpBuffer = 0;
}
ImageInfo::~ImageInfo(){
	if(imageData && autoDel)
		delete [] imageData;

	if (tmpBuffer)
		delete tmpBuffer;
}

int ImageInfo::getPitch()const{
	return Size.x*PixelUtil::getPixelDescription(format).elemSizeB;
}

void ImageInfo::clear(){
	delete [] imageData;
	imageDataSize=0;
	imageData=0;
	Size = Vector2d(0,0);
}

void ImageInfo::setData(const void*data, const Vector2d&size, EPixelFormat format){

	if(Size!=size || format != this->format)
	{
		clear();
		Size=size;
		this->format=format;
		imageDataSize=Size.x*Size.y*PixelUtil::getPixelDescription(format).elemSizeB;
		if(imageDataSize>0)
			imageData=new uchar[imageDataSize];
		else
			return;

	}
	memcpy(imageData,data,imageDataSize);
}

void ImageInfo::copyFrom(const ImageInfo* i)
{
    setData(i->imageData,i->Size,i->format);
}

void wrapValues(Vector2d& pos, Vector2d size)
{

}

inline float clip(float v, float a, float b)
{
	return max(min(v, b), a);
}

void ImageInfo::_copyCroppedFromI420(const ImageInfo* src, Vector2d pos, Vector2d sz, bool clamp, EPixelFormat targetFormat)
{
	if (targetFormat == EPixel_Alpha8 ||
		targetFormat == EPixel_LUMINANCE8)
		targetFormat = EPixel_Alpha8;
	else
		targetFormat = EPixel_R8G8B8;

	//Sample only Y Channel
	createData(Vector2d(sz.x, sz.y), targetFormat);

	//copy pixels
	bool wrapX = false;
	bool wrapY = false;

	int targetHeight = src->Size.y * 2 / 3;

	if (pos.x<0)
	{
		pos.x += src->Size.x;
	}
	else if (pos.x >= src->Size.x)
	{
		pos.x -= src->Size.x;
	}
	if (pos.y<0)
	{
		pos.y += targetHeight;
	}
	else if (pos.y >= targetHeight)
	{
		pos.y -= src->Size.y;
	}

	if (sz.x>src->Size.x)sz.x = src->Size.x;
	if (sz.y>targetHeight)sz.y = targetHeight;

	if (sz.x + pos.x>src->Size.x)wrapX = true;
	if (sz.y + pos.y>targetHeight)wrapY = true;

	const uchar* srcPtr0 = src->imageData;
	uchar* dstPtr = imageData;

	int srcRowpitch = src->Size.x;

	if(targetFormat==EPixel_Alpha8)
	{

		int rowpitch = sz.x;

		//flip contents Vertically
		// dstPtr+=rowpitch*(sz.y-1);

		int y0 = pos.y;
		int srcOffset = y0*srcRowpitch;
		for (int i = 0; i<sz.y; ++i)
		{
			if (y0 >= targetHeight)
			{
				y0 = 0;
			}
			srcOffset = y0*srcRowpitch;

			const uchar* srcPtr = srcPtr0 + srcOffset;
			if (!wrapX)
			{
				//copy Y
				memcpy(dstPtr, srcPtr + pos.x, rowpitch);
				if (targetFormat == EPixel_I420)
				{
					//look up U

				}
			}
			else
			{
				//copy two parts
				//[******-------******]
				// ^****^       ^****^
				// >>p2>>       S>>p1>

				int S = pos.x;
				int p1 = src->Size.x - S;
				int p2 = sz.x - p1;
				memcpy(dstPtr, srcPtr + S, p1);
				memcpy(dstPtr + p1, srcPtr, p2);

			}

			y0++;
			//dstPtr-=rowpitch;
			dstPtr += rowpitch;

		}
	}
	else
	{

		//Sample RGB data. Slower process due to YUV to RGB conversion
		static const float YUVOffset[] = { -0.0625f * 255, -0.5f * 255, -0.5f * 255 };
		static const float YUV1[] = { 1.164f ,  0.000f ,  1.596f };
		static const float YUV2[] = { 1.164f , -0.391f , -0.813f };
		static const float YUV3[] = { 1.164f ,  2.018f ,  0.000f };

			/*
			static const float YUVOffset[] = { 0, 0,0 };
		static const float YUV1[] = { 1 ,  0.000f ,  1.140f };
		static const float YUV2[] = { 1 , -0.395f , -0.581f };
		static const float YUV3[] = { 1 ,  2.032f ,  0.000f };
		*/

		int targetHeight = src->Size.y * 2 / 3;
		//row offset
		/*int YOffset = 0;
		int YCount = src->Size.y * 2 / 3;
		int UOffset = src->Size.y*4.0f / 6.0f;
		int UCount = src->Size.y / 6;
		int VOffset = src->Size.y*5.0f / 6.0f;
		int VCount = src->Size.y / 6;*/

#define SAMPLE(X,Y)((Y)*srcRowpitch+(X))

		int YUVSample[3];
		int y0 = pos.y;
		for (int i = 0; i<sz.y; ++i)
		{
			if (y0 >= targetHeight)//wrap Y
			{
				y0 = 0;
			}
			int x0 = pos.x;
			for (int j = 0; j < sz.x; ++j)
			{
				if (x0 >= src->Size.x)//wrap X
				{
					x0 = 0;
				}

				int y1 = y0 ;
				YUVSample[0] = (srcPtr0[SAMPLE(x0, y1)])-16;// +YUVOffset[0];

				int x1 = x0/2;
				if (y1 % 2 == 0)
					x1 += src->Size.x / 2;

				y1 = (y1 / 4) + targetHeight;
				YUVSample[1] = (srcPtr0[SAMPLE(x1, y1)])-128;// +YUVOffset[1];
				y1 += targetHeight / 4;
				YUVSample[2] = (srcPtr0[SAMPLE(x1, y1)]) - 128;//+ YUVOffset[2];

				dstPtr[0] = (uchar)clip((YUVSample[0] *298						+ YUVSample[2] * 409 + 128)>>8,0,255);
				dstPtr[1] = (uchar)clip((YUVSample[0] *298 - YUVSample[1] *100 - YUVSample[2] *208  + 128)>>8,0,255);
				dstPtr[2] = (uchar)clip((YUVSample[0] *298 + YUVSample[1] *516						 + 128)>>8,0,255);

				dstPtr += 3;
				++x0;
			}

			++y0;
			//dstPtr-=rowpitch;
			//dstPtr += rowpitch;
		}
	}
}
void ImageInfo::copyCroppedFrom(const ImageInfo* src,Vector2d pos,Vector2d sz,bool clamp,
                                EPixelFormat targetFormat)
{
    if(clamp)
    {
        if(pos.x<0)pos.x=0;
        if(pos.y<0)pos.y=0;
        if(sz.x+pos.x>src->Size.x)sz.x=src->Size.x-pos.x;
        if(sz.y+pos.y>src->Size.y)sz.y=src->Size.y-pos.y;
    }
    //else allow wrap data

    if(src->format==EPixel_I420)
    {
		_copyCroppedFromI420(src, pos, sz, clamp, targetFormat);
	}
	else
	{

	}
}

void ImageInfo::FlipImage(bool horizontal,bool vertical)
{
    if(!horizontal && !vertical)
        return;

    int Rows=Size.y;
    int Cols=Size.x/2;
    if(vertical)
        Rows/=2;

    int rowPitch=(imageDataSize/Size.y)*sizeof(uchar);

    uchar* newData=new uchar[imageDataSize];

    uchar* srcPtr=imageData;
    uchar* dstPtr=newData;

    int y0=0;
    int y1=(Size.y-1)*rowPitch;

    for(int y=0;y<Rows;++y)
    {
        if(vertical)
        {
            //flip rows contents
            memcpy(dstPtr+y0,srcPtr+y1,rowPitch*sizeof(uchar));
            memcpy(dstPtr+y1,srcPtr+y0,rowPitch*sizeof(uchar));
        }
        if(horizontal)
        {
            uchar* ptr0=dstPtr+y0;
            uchar* ptr1=dstPtr+y0+rowPitch-1;
            for(int x=0;x<Cols;++x)
            {
                uchar t=*ptr0;
                *ptr0=*ptr1;
                *ptr1=t;
                ++ptr0;
                --ptr1;
            }
            if(Size.x%2==1)
            {
                *ptr0=*ptr1;
            }
        }

        y0+=rowPitch;
        y1-=rowPitch;
    }

    if(vertical && Size.y%2==1)
    {
        //copy the middle row
        memcpy(dstPtr+(Size.y/2+1)*rowPitch,srcPtr+(Size.y/2+1)*rowPitch,rowPitch);
    }

    delete [] imageData;
    imageData=newData;
}
void ImageInfo::createData(const Vector2d& size, EPixelFormat format){
	if(Size==size && format == this->format)
		return;
	clear();
	Size=size;
	this->format=format;

	imageDataSize=Size.x*Size.y*PixelUtil::getPixelDescription(format).elemSizeB;
	if(imageDataSize>0){
		imageData=new uchar[imageDataSize];
		//mraySystem::memSet(imageData,0,imageDataSize);
	}
}

uchar*ImageInfo::getSurface(int d){
	return imageData+(Size.x*Size.y*PixelUtil::getPixelDescription(format).elemSizeB);
}

const uchar*ImageInfo::getSurface(int d)const
{
	return imageData+(Size.x*Size.y*PixelUtil::getPixelDescription(format).elemSizeB);
}

}
}
<commit_msg>Log warning when requesting unsupported color conversions<commit_after>#include "stdafx.h"

#include "ImageInfo.h"

#include "PixelUtil.h"
#include <string>

#define min(a, b) (((a) < (b)) ? (a) : (b))
#define max(a, b) (((a) < (b)) ? (b) : (a))

namespace mray{
namespace video{

ImageInfo::ImageInfo():format(EPixel_LUMINANCE8),
		imageData(0),imageDataSize(0)
{
	autoDel=true;
	tmpBuffer = 0;
}
ImageInfo::~ImageInfo(){
	if(imageData && autoDel)
		delete [] imageData;

	if (tmpBuffer)
		delete tmpBuffer;
}

int ImageInfo::getPitch()const{
	return Size.x*PixelUtil::getPixelDescription(format).elemSizeB;
}

void ImageInfo::clear(){
	delete [] imageData;
	imageDataSize=0;
	imageData=0;
	Size = Vector2d(0,0);
}

void ImageInfo::setData(const void*data, const Vector2d&size, EPixelFormat format){

	if(Size!=size || format != this->format)
	{
		clear();
		Size=size;
		this->format=format;
		imageDataSize=Size.x*Size.y*PixelUtil::getPixelDescription(format).elemSizeB;
		if(imageDataSize>0)
			imageData=new uchar[imageDataSize];
		else
			return;

	}
	memcpy(imageData,data,imageDataSize);
}

void ImageInfo::copyFrom(const ImageInfo* i)
{
    setData(i->imageData,i->Size,i->format);
}

void wrapValues(Vector2d& pos, Vector2d size)
{

}

inline float clip(float v, float a, float b)
{
	return max(min(v, b), a);
}

void ImageInfo::_copyCroppedFromI420(const ImageInfo* src, Vector2d pos, Vector2d sz, bool clamp, EPixelFormat targetFormat)
{
	if (targetFormat == EPixel_Alpha8 ||
		targetFormat == EPixel_LUMINANCE8)
		targetFormat = EPixel_Alpha8;
	else
		targetFormat = EPixel_R8G8B8;

	//Sample only Y Channel
	createData(Vector2d(sz.x, sz.y), targetFormat);

	//copy pixels
	bool wrapX = false;
	bool wrapY = false;

	int targetHeight = src->Size.y * 2 / 3;

	if (pos.x<0)
	{
		pos.x += src->Size.x;
	}
	else if (pos.x >= src->Size.x)
	{
		pos.x -= src->Size.x;
	}
	if (pos.y<0)
	{
		pos.y += targetHeight;
	}
	else if (pos.y >= targetHeight)
	{
		pos.y -= src->Size.y;
	}

	if (sz.x>src->Size.x)sz.x = src->Size.x;
	if (sz.y>targetHeight)sz.y = targetHeight;

	if (sz.x + pos.x>src->Size.x)wrapX = true;
	if (sz.y + pos.y>targetHeight)wrapY = true;

	const uchar* srcPtr0 = src->imageData;
	uchar* dstPtr = imageData;

	int srcRowpitch = src->Size.x;

	if(targetFormat==EPixel_Alpha8)
	{

		int rowpitch = sz.x;

		//flip contents Vertically
		// dstPtr+=rowpitch*(sz.y-1);

		int y0 = pos.y;
		int srcOffset = y0*srcRowpitch;
		for (int i = 0; i<sz.y; ++i)
		{
			if (y0 >= targetHeight)
			{
				y0 = 0;
			}
			srcOffset = y0*srcRowpitch;

			const uchar* srcPtr = srcPtr0 + srcOffset;
			if (!wrapX)
			{
				//copy Y
				memcpy(dstPtr, srcPtr + pos.x, rowpitch);
				if (targetFormat == EPixel_I420)
				{
					//look up U

				}
			}
			else
			{
				//copy two parts
				//[******-------******]
				// ^****^       ^****^
				// >>p2>>       S>>p1>

				int S = pos.x;
				int p1 = src->Size.x - S;
				int p2 = sz.x - p1;
				memcpy(dstPtr, srcPtr + S, p1);
				memcpy(dstPtr + p1, srcPtr, p2);

			}

			y0++;
			//dstPtr-=rowpitch;
			dstPtr += rowpitch;

		}
	}
	else
	{

		//Sample RGB data. Slower process due to YUV to RGB conversion
		static const float YUVOffset[] = { -0.0625f * 255, -0.5f * 255, -0.5f * 255 };
		static const float YUV1[] = { 1.164f ,  0.000f ,  1.596f };
		static const float YUV2[] = { 1.164f , -0.391f , -0.813f };
		static const float YUV3[] = { 1.164f ,  2.018f ,  0.000f };

			/*
			static const float YUVOffset[] = { 0, 0,0 };
		static const float YUV1[] = { 1 ,  0.000f ,  1.140f };
		static const float YUV2[] = { 1 , -0.395f , -0.581f };
		static const float YUV3[] = { 1 ,  2.032f ,  0.000f };
		*/

		int targetHeight = src->Size.y * 2 / 3;
		//row offset
		/*int YOffset = 0;
		int YCount = src->Size.y * 2 / 3;
		int UOffset = src->Size.y*4.0f / 6.0f;
		int UCount = src->Size.y / 6;
		int VOffset = src->Size.y*5.0f / 6.0f;
		int VCount = src->Size.y / 6;*/

#define SAMPLE(X,Y)((Y)*srcRowpitch+(X))

		int YUVSample[3];
		int y0 = pos.y;
		for (int i = 0; i<sz.y; ++i)
		{
			if (y0 >= targetHeight)//wrap Y
			{
				y0 = 0;
			}
			int x0 = pos.x;
			for (int j = 0; j < sz.x; ++j)
			{
				if (x0 >= src->Size.x)//wrap X
				{
					x0 = 0;
				}

				int y1 = y0 ;
				YUVSample[0] = (srcPtr0[SAMPLE(x0, y1)])-16;// +YUVOffset[0];

				int x1 = x0/2;
				if (y1 % 2 == 0)
					x1 += src->Size.x / 2;

				y1 = (y1 / 4) + targetHeight;
				YUVSample[1] = (srcPtr0[SAMPLE(x1, y1)])-128;// +YUVOffset[1];
				y1 += targetHeight / 4;
				YUVSample[2] = (srcPtr0[SAMPLE(x1, y1)]) - 128;//+ YUVOffset[2];

				dstPtr[0] = (uchar)clip((YUVSample[0] *298						+ YUVSample[2] * 409 + 128)>>8,0,255);
				dstPtr[1] = (uchar)clip((YUVSample[0] *298 - YUVSample[1] *100 - YUVSample[2] *208  + 128)>>8,0,255);
				dstPtr[2] = (uchar)clip((YUVSample[0] *298 + YUVSample[1] *516						 + 128)>>8,0,255);

				dstPtr += 3;
				++x0;
			}

			++y0;
			//dstPtr-=rowpitch;
			//dstPtr += rowpitch;
		}
	}
}
void ImageInfo::copyCroppedFrom(const ImageInfo* src,Vector2d pos,Vector2d sz,bool clamp,
                                EPixelFormat targetFormat)
{
    if(clamp)
    {
        if(pos.x<0)pos.x=0;
        if(pos.y<0)pos.y=0;
        if(sz.x+pos.x>src->Size.x)sz.x=src->Size.x-pos.x;
        if(sz.y+pos.y>src->Size.y)sz.y=src->Size.y-pos.y;
    }
    //else allow wrap data

    if(src->format==EPixel_I420)
    {
		_copyCroppedFromI420(src, pos, sz, clamp, targetFormat);
	}
	else
	{
		LogManager::Instance()->LogMessage(
			"ImageInfo - WARNING: Conversion requested from pixel format " + std::to_string(src->format) + " to " +
			std::to_string(targetFormat) + ", which is currently not supported, and was ignored."
		);
	}
}

void ImageInfo::FlipImage(bool horizontal,bool vertical)
{
    if(!horizontal && !vertical)
        return;

    int Rows=Size.y;
    int Cols=Size.x/2;
    if(vertical)
        Rows/=2;

    int rowPitch=(imageDataSize/Size.y)*sizeof(uchar);

    uchar* newData=new uchar[imageDataSize];

    uchar* srcPtr=imageData;
    uchar* dstPtr=newData;

    int y0=0;
    int y1=(Size.y-1)*rowPitch;

    for(int y=0;y<Rows;++y)
    {
        if(vertical)
        {
            //flip rows contents
            memcpy(dstPtr+y0,srcPtr+y1,rowPitch*sizeof(uchar));
            memcpy(dstPtr+y1,srcPtr+y0,rowPitch*sizeof(uchar));
        }
        if(horizontal)
        {
            uchar* ptr0=dstPtr+y0;
            uchar* ptr1=dstPtr+y0+rowPitch-1;
            for(int x=0;x<Cols;++x)
            {
                uchar t=*ptr0;
                *ptr0=*ptr1;
                *ptr1=t;
                ++ptr0;
                --ptr1;
            }
            if(Size.x%2==1)
            {
                *ptr0=*ptr1;
            }
        }

        y0+=rowPitch;
        y1-=rowPitch;
    }

    if(vertical && Size.y%2==1)
    {
        //copy the middle row
        memcpy(dstPtr+(Size.y/2+1)*rowPitch,srcPtr+(Size.y/2+1)*rowPitch,rowPitch);
    }

    delete [] imageData;
    imageData=newData;
}
void ImageInfo::createData(const Vector2d& size, EPixelFormat format){
	if(Size==size && format == this->format)
		return;
	clear();
	Size=size;
	this->format=format;

	imageDataSize=Size.x*Size.y*PixelUtil::getPixelDescription(format).elemSizeB;
	if(imageDataSize>0){
		imageData=new uchar[imageDataSize];
		//mraySystem::memSet(imageData,0,imageDataSize);
	}
}

uchar*ImageInfo::getSurface(int d){
	return imageData+(Size.x*Size.y*PixelUtil::getPixelDescription(format).elemSizeB);
}

const uchar*ImageInfo::getSurface(int d)const
{
	return imageData+(Size.x*Size.y*PixelUtil::getPixelDescription(format).elemSizeB);
}

}
}
<|endoftext|>