<commit_before>
//
//		MMMAN : Multimedia manager source
//				for Windows95/NT 32bit enviroment
//					onion software/onitama 1997/8
//

#include <windows.h>
#include <windowsx.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <tchar.h>

/*
	rev 43
	mingw : error : sȊ֐ tolower
	ɑΏ
*/
#if defined( __GNUC__ )
#include <ctype.h>
#endif

#include "../supio.h"
#include "../dpmread.h"
#include "../strbuf.h"
#include "mmman.h"

/*
	rev 43
	mingw : warning : #pragma comment 𖳎
	ɑΏ
*/
#if defined( _MSC_VER )
#pragma comment(lib,"winmm.lib")
#endif

#ifdef HSPUTF8
#pragma execution_character_set("utf-8")
#endif

#define sndbank(a) (char *)(mem_snd[a].mempt)

void MMMan::SendMCIT(TCHAR *ss)
{
	char *ss8;
	apichartohspchar(ss,&ss8);
	SendMCI( ss8 );
	freehc(&ss8);
}

MMMan::MMMan()
{
	//		initalize MM manager
	//
	mem_snd = NULL;
	mm_cur = 0;
}

MMMan::~MMMan()
{
	//		terminate MM manager
	//
	ClearAllBank();
}

void MMMan::DeleteBank( int bank )
{
	char *lpSnd;
	lpSnd = sndbank( bank );
	if ( lpSnd != NULL ) {
		free( lpSnd );
	}
	mem_snd[bank].mempt=NULL;
	if ( mem_snd[bank].fname != NULL ) {
		free( mem_snd[bank].fname );
		mem_snd[bank].fname = NULL;
	}
}

int MMMan::SearchBank( int num )
{
	int a;
	for(a=0;a<mm_cur;a++) {
		if ( mem_snd[a].num == num ) return a;
	}
	return -1;
}

MMM *MMMan::SetBank( int num, int flag, int opt, void *mempt, char *fname )
{
	int bank;
	MMM *m;

	bank = SearchBank( num );
	if ( bank < 0 ) {
		bank = AllocBank();
	} else {
		DeleteBank( bank );
	}

	m = &(mem_snd[bank]);
	m->flag = flag;
	m->opt = opt;
	m->num = num;
	m->vol = 0;
	m->pan = 0;
	m->mempt = mempt;
	m->fname = NULL;

	if ( fname != NULL ) {
		m->fname = (char *)malloc( strlen( fname )+1 );
		strcpy( m->fname, fname );
	}
	return m;
}

int MMMan::AllocBank( void )
{
	int id,sz;
	id = mm_cur++;
	sz = mm_cur * sizeof(MMM);
	if ( mem_snd == NULL ) {
		mem_snd = (MMM *)sbAlloc( sz );
	} else {
		mem_snd = (MMM *)sbExpand( (char *)mem_snd, sz );
	}
	mem_snd[id].flag = MMDATA_NONE;
	mem_snd[id].num = -1;
	return id;
}

void MMMan::ClearAllBank( void )
{
	int a;
	if ( mem_snd != NULL ) {
		Stop();
		for(a=0;a<mm_cur;a++) {
			DeleteBank( a );
		}
		sbFree( mem_snd );
		mem_snd = NULL;
		mm_cur = 0;
	}
}

void MMMan::Reset( HWND hwnd )
{
	ClearAllBank();
	hwm = hwnd;
	avi_wnd = hwnd;
	curmus=-1;
}

int MMMan::SendMCI( char *mci_commands )
{
	int a;
	HSPAPICHAR *hactmp1 = 0;
	HSPAPICHAR *hactmp2 = 0;
	a=mciSendString( chartoapichar(mci_commands,&hactmp1),chartoapichar(res,&hactmp2),256,hwm );
	freehac(&hactmp1);
	freehac(&hactmp2);
	if (a) return -1;
	return atoi(res);
}

char *MMMan::GetMCIResult( void )
{
	return res;
}

void MMMan::SetWindow( HWND hwnd, int x, int y, int sx, int sy )
{
	avi_wnd = hwnd;
	avi_x = x; avi_y = y;
	avi_sx = sx; avi_sy = sy;
}

void MMMan::Stop( void )
{
	//		stop playing sound
	//
	sndPlaySound(NULL, 0);				// stop PCM sound
	if (curmus!=-1) {
		SendMCI("stop myid");
		SendMCI("close myid");
		curmus=-1;
	}
}

/*
	rev 43
	mingw : warning : a ͑OɎg
	ɑΏB
	ۂɂ͂肦ȂB
*/
int MMMan::Load( char *fname, int num, int opt )
{
	//		Load sound to bank
	//			opt : 0=normal/1=loop/2=wait/3=continuous
	//
	int a = 1,getlen;
	char fext[8];
	char a1,a2,a3;
	char *pt;
	int flag;
	MMM *mmm;
	HSPAPICHAR *hactmp1 = 0;
	HSPAPICHAR wfext[9];

	flag = MMDATA_MCIVOICE;
	pt = NULL;

	a1=tolower(fname[0]);
	a2=tolower(fname[1]);
	a3=fname[2];
	if ((a1=='c')&&(a2=='d')&&(a3==':')) {	// when "CD"
		flag = MMDATA_CDAUDIO;
		a = atoi( fname+3 );if ( a<1 ) a=1;
	}

	getpathW(chartoapichar(fname,&hactmp1),wfext,16+2);				// gqŎo

	if (!_tcscmp(wfext,TEXT(".avi"))) {				// when "AVI"
		flag = MMDATA_MCIVIDEO;
	}

	if (!_tcscmp(wfext,TEXT(".wmv"))) {				// when "WMV"
		flag = MMDATA_MCIVIDEO;
	}

	if (!_tcscmp(wfext,TEXT(".mpg"))) {				// when "MPG"
		flag = MMDATA_MPEGVIDEO;
	}

	if (!_tcscmp(wfext,TEXT(".wav"))) {				// when "WAV"
		getlen = dpm_exist( fname );
		if (getlen == -1) {
			freehac(&hactmp1);
			return 1;
		}
		if ( getlen < 2000000 ) {			// 2MBȏMCIĐ
			pt = (char *)malloc( getlen+16 );
			dpm_read( fname, pt, getlen, 0 );
			flag = MMDATA_INTWAVE;
		}
	}
	freehac(&hactmp1);

	mmm = SetBank( num, flag, opt, pt, fname );

	if ( flag == MMDATA_CDAUDIO ) {
		mmm->track = a;
		mmm->lasttrk = SendMCI( "status cdaudio number of tracks" );
	}
	return 0;
}

int MMMan::Play( int num )
{
	//		Play sound
	//
	int a,i,j,flg;
	int prm;
	int bank;
	TCHAR ss[1024];
	TCHAR fpath[MAX_PATH];
	MMM *mmm;
	HSPAPICHAR *hactmp1 = 0;

	bank = SearchBank( num );
	if ( bank < 0 ) return 1;

	mmm=&mem_snd[bank];
	a=mmm->opt;
	flg=mmm->flag;
	if ((flg>1)&&(curmus!=-1)) Stop();
	switch(flg) {

		case MMDATA_INTWAVE:							// when "WAV"

			prm=SND_MEMORY | SND_NODEFAULT;
			if (a==0) prm|=SND_ASYNC;
			if (a==1) prm|=SND_LOOP | SND_ASYNC;
			if (a==2) prm|=SND_SYNC;
#ifdef HSPUTF8
			sndPlaySound( chartoapichar((char*)mmm->mempt,&hactmp1),prm );
			freehac(&hactmp1);
#else
			sndPlaySound( (LPCSTR)mmm->mempt,prm);
#endif
			return 0;

		case MMDATA_MCIVOICE:							// when "MID" file
		case MMDATA_MCIVIDEO:							// when "AVI" file
		case MMDATA_MPEGVIDEO:							// when "MPG" file

			if ( GetShortPathName( chartoapichar(mmm->fname,&hactmp1), fpath, MAX_PATH ) == 0 ) {
				freehac(&hactmp1);
				return 1;
			}
			freehac(&hactmp1);
			if ( flg!=MMDATA_MPEGVIDEO ) {
				_stprintf( ss,TEXT("open %s alias myid"),fpath );
			} else {
				_stprintf( ss,TEXT("open %s type MPEGVIDEO alias myid"),fpath );
			}
			SendMCIT( ss );
			if (flg!=MMDATA_MCIVOICE) {
				if ( SendMCI( "where myid source" )==0 ) strcpy( avi_wh,res+4 );
				if ( a&16 ) {
					sprintf( avi_wh,"%d %d",avi_sx,avi_sy );
					avi_x=0;avi_y=0;
				}
				_stprintf( ss,TEXT("window myid handle %u"), (unsigned)HandleToUlong(avi_wnd) );
				SendMCIT( ss );
				_stprintf( ss,TEXT("put myid destination at %d %d %s"),avi_x,avi_y,chartoapichar(avi_wh,&hactmp1) );
				freehac(&hactmp1);
				SendMCIT( ss );
			}
			_tcscpy( ss,TEXT("play myid from 0") );
			break;

		case MMDATA_CDAUDIO:							// when "CD audio"

			SendMCI( "open cdaudio alias myid" );
			SendMCI( "set myid time format tmsf" );

			i=mmm->track;j=mmm->lasttrk;
			if ((i==j)||(a==3)) {
				_stprintf( ss,TEXT("play myid from %d"),i );
			} else {
				_stprintf( ss,TEXT("play myid from %d to %d"),i,i+1 );
			}
			break;
	}

	a&=15;
	if (a==1) _tcscat( ss,TEXT(" notify") );
	if (a==2) _tcscat( ss,TEXT(" wait") );
	SendMCIT(ss);
	curmus = num;

	if ( mmm->vol != 0 ) { SetVol( num, mmm->vol ); }

	return 0;
}

void MMMan::Notify( void )
{
	//		callback from windows message
	//			"MM_MCINOTIFY"
	//
	int a;
	a=curmus;
	if (curmus!=-1) {
		SendMCI("stop myid");
		SendMCI("close myid");
		curmus=-1;
	}
	Play( a );
}

void MMMan::GetInfo( int bank, char **fname, int *num, int *flag, int *opt )
{
	//		Get MMM info
	//
	MMM *mmm;
	mmm=&mem_snd[bank];
	*fname = mmm->fname;
	*opt=mmm->opt;
	*flag=mmm->flag;
	*num=mmm->num;
}

/*
int MMMan::GetBusy( void )
{
	//		wavĐ𒲂ׂ
	//
	if ( sndPlaySound( (LPCSTR)"",SND_NOSTOP|SND_NODEFAULT ) == FALSE ) {
		return 1;
	}
	return 0;
}
*/

void MMMan::SetVol( int num, int vol )
{
	MMM *mmm;
	int bank,flg;
	char ss[1024];
	bank = SearchBank( num );
	if ( bank < 0 ) return;

	mmm=&mem_snd[bank];
	mmm->vol = vol;
	if ( mmm->vol > 0 ) mmm->vol = 0;
	if ( mmm->vol < -1000 ) mmm->vol = -1000;

	flg=mmm->flag;
	switch(flg) {
	case MMDATA_INTWAVE:							// when "WAV"
		//
		break;
	case MMDATA_MCIVOICE:							// when "MID" file
	case MMDATA_MCIVIDEO:							// when "AVI" file
	case MMDATA_MPEGVIDEO:							// when "MPG" file
		if ( curmus != -1 ) {
			int mcivol;
			mcivol = mmm->vol + 1000;
			sprintf( ss,"setaudio myid volume to %d",mcivol );
			SendMCI( ss );
		}
		break;
	}
}

void MMMan::SetPan( int num, int pan )
{
	MMM *mmm;
	int bank,flg;
	bank = SearchBank( num );
	if ( bank < 0 ) return;

	mmm=&mem_snd[bank];
	flg=mmm->flag;
	switch(flg) {
	case MMDATA_INTWAVE:							// when "WAV"
		//
		break;
	}
}

int MMMan::GetStatus( int num, int infoid )
{
	MMM *mmm;
	int bank,flg;
	int res;
	bank = SearchBank( num );
	if ( bank < 0 ) return 0;

	mmm=&mem_snd[bank];
	flg=mmm->flag;
	res = 0;
	switch( infoid ) {
	case 0:
		res = mmm->opt;
		break;
	case 1:
		res = mmm->vol;
		break;
	case 2:
		res = mmm->pan;
		break;
	case 16:
		if (( flg == MMDATA_MCIVOICE )||( flg == MMDATA_MCIVIDEO )||( flg == MMDATA_MPEGVIDEO )) {
			if (curmus!=-1) res = 1;
		}
		break;
	}
	return res;
}

<commit_msg>hsp3utfのmmplayで2MB未満のwavファイルが再生できなかった問題を修正<commit_after>
//
//		MMMAN : Multimedia manager source
//				for Windows95/NT 32bit enviroment
//					onion software/onitama 1997/8
//

#include <windows.h>
#include <windowsx.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <tchar.h>

/*
	rev 43
	mingw : error : sȊ֐ tolower
	ɑΏ
*/
#if defined( __GNUC__ )
#include <ctype.h>
#endif

#include "../supio.h"
#include "../dpmread.h"
#include "../strbuf.h"
#include "mmman.h"

/*
	rev 43
	mingw : warning : #pragma comment 𖳎
	ɑΏ
*/
#if defined( _MSC_VER )
#pragma comment(lib,"winmm.lib")
#endif

#ifdef HSPUTF8
#pragma execution_character_set("utf-8")
#endif

#define sndbank(a) (char *)(mem_snd[a].mempt)

void MMMan::SendMCIT(TCHAR *ss)
{
	char *ss8;
	apichartohspchar(ss,&ss8);
	SendMCI( ss8 );
	freehc(&ss8);
}

MMMan::MMMan()
{
	//		initalize MM manager
	//
	mem_snd = NULL;
	mm_cur = 0;
}

MMMan::~MMMan()
{
	//		terminate MM manager
	//
	ClearAllBank();
}

void MMMan::DeleteBank( int bank )
{
	char *lpSnd;
	lpSnd = sndbank( bank );
	if ( lpSnd != NULL ) {
		free( lpSnd );
	}
	mem_snd[bank].mempt=NULL;
	if ( mem_snd[bank].fname != NULL ) {
		free( mem_snd[bank].fname );
		mem_snd[bank].fname = NULL;
	}
}

int MMMan::SearchBank( int num )
{
	int a;
	for(a=0;a<mm_cur;a++) {
		if ( mem_snd[a].num == num ) return a;
	}
	return -1;
}

MMM *MMMan::SetBank( int num, int flag, int opt, void *mempt, char *fname )
{
	int bank;
	MMM *m;

	bank = SearchBank( num );
	if ( bank < 0 ) {
		bank = AllocBank();
	} else {
		DeleteBank( bank );
	}

	m = &(mem_snd[bank]);
	m->flag = flag;
	m->opt = opt;
	m->num = num;
	m->vol = 0;
	m->pan = 0;
	m->mempt = mempt;
	m->fname = NULL;

	if ( fname != NULL ) {
		m->fname = (char *)malloc( strlen( fname )+1 );
		strcpy( m->fname, fname );
	}
	return m;
}

int MMMan::AllocBank( void )
{
	int id,sz;
	id = mm_cur++;
	sz = mm_cur * sizeof(MMM);
	if ( mem_snd == NULL ) {
		mem_snd = (MMM *)sbAlloc( sz );
	} else {
		mem_snd = (MMM *)sbExpand( (char *)mem_snd, sz );
	}
	mem_snd[id].flag = MMDATA_NONE;
	mem_snd[id].num = -1;
	return id;
}

void MMMan::ClearAllBank( void )
{
	int a;
	if ( mem_snd != NULL ) {
		Stop();
		for(a=0;a<mm_cur;a++) {
			DeleteBank( a );
		}
		sbFree( mem_snd );
		mem_snd = NULL;
		mm_cur = 0;
	}
}

void MMMan::Reset( HWND hwnd )
{
	ClearAllBank();
	hwm = hwnd;
	avi_wnd = hwnd;
	curmus=-1;
}

int MMMan::SendMCI( char *mci_commands )
{
	int a;
	HSPAPICHAR *hactmp1 = 0;
	HSPAPICHAR *hactmp2 = 0;
	a=mciSendString( chartoapichar(mci_commands,&hactmp1),chartoapichar(res,&hactmp2),256,hwm );
	freehac(&hactmp1);
	freehac(&hactmp2);
	if (a) return -1;
	return atoi(res);
}

char *MMMan::GetMCIResult( void )
{
	return res;
}

void MMMan::SetWindow( HWND hwnd, int x, int y, int sx, int sy )
{
	avi_wnd = hwnd;
	avi_x = x; avi_y = y;
	avi_sx = sx; avi_sy = sy;
}

void MMMan::Stop( void )
{
	//		stop playing sound
	//
	sndPlaySound(NULL, 0);				// stop PCM sound
	if (curmus!=-1) {
		SendMCI("stop myid");
		SendMCI("close myid");
		curmus=-1;
	}
}

/*
	rev 43
	mingw : warning : a ͑OɎg
	ɑΏB
	ۂɂ͂肦ȂB
*/
int MMMan::Load( char *fname, int num, int opt )
{
	//		Load sound to bank
	//			opt : 0=normal/1=loop/2=wait/3=continuous
	//
	int a = 1,getlen;
	char fext[8];
	char a1,a2,a3;
	char *pt;
	int flag;
	MMM *mmm;
	HSPAPICHAR *hactmp1 = 0;
	HSPAPICHAR wfext[9];

	flag = MMDATA_MCIVOICE;
	pt = NULL;

	a1=tolower(fname[0]);
	a2=tolower(fname[1]);
	a3=fname[2];
	if ((a1=='c')&&(a2=='d')&&(a3==':')) {	// when "CD"
		flag = MMDATA_CDAUDIO;
		a = atoi( fname+3 );if ( a<1 ) a=1;
	}

	getpathW(chartoapichar(fname,&hactmp1),wfext,16+2);				// gqŎo

	if (!_tcscmp(wfext,TEXT(".avi"))) {				// when "AVI"
		flag = MMDATA_MCIVIDEO;
	}

	if (!_tcscmp(wfext,TEXT(".wmv"))) {				// when "WMV"
		flag = MMDATA_MCIVIDEO;
	}

	if (!_tcscmp(wfext,TEXT(".mpg"))) {				// when "MPG"
		flag = MMDATA_MPEGVIDEO;
	}

	if (!_tcscmp(wfext,TEXT(".wav"))) {				// when "WAV"
		getlen = dpm_exist( fname );
		if (getlen == -1) {
			freehac(&hactmp1);
			return 1;
		}
		if ( getlen < 2000000 ) {			// 2MBȏMCIĐ
			pt = (char *)malloc( getlen+16 );
			dpm_read( fname, pt, getlen, 0 );
			flag = MMDATA_INTWAVE;
		}
	}
	freehac(&hactmp1);

	mmm = SetBank( num, flag, opt, pt, fname );

	if ( flag == MMDATA_CDAUDIO ) {
		mmm->track = a;
		mmm->lasttrk = SendMCI( "status cdaudio number of tracks" );
	}
	return 0;
}

int MMMan::Play( int num )
{
	//		Play sound
	//
	int a,i,j,flg;
	int prm;
	int bank;
	TCHAR ss[1024];
	TCHAR fpath[MAX_PATH];
	MMM *mmm;
	HSPAPICHAR *hactmp1 = 0;

	bank = SearchBank( num );
	if ( bank < 0 ) return 1;

	mmm=&mem_snd[bank];
	a=mmm->opt;
	flg=mmm->flag;
	if ((flg>1)&&(curmus!=-1)) Stop();
	switch(flg) {

		case MMDATA_INTWAVE:							// when "WAV"

			prm=SND_MEMORY | SND_NODEFAULT;
			if (a==0) prm|=SND_ASYNC;
			if (a==1) prm|=SND_LOOP | SND_ASYNC;
			if (a==2) prm|=SND_SYNC;
#ifdef HSPUTF8
			sndPlaySound( (LPCTSTR)mmm->mempt,prm );
#else
			sndPlaySound( (LPCSTR)mmm->mempt,prm);
#endif
			return 0;

		case MMDATA_MCIVOICE:							// when "MID" file
		case MMDATA_MCIVIDEO:							// when "AVI" file
		case MMDATA_MPEGVIDEO:							// when "MPG" file

			if ( GetShortPathName( chartoapichar(mmm->fname,&hactmp1), fpath, MAX_PATH ) == 0 ) {
				freehac(&hactmp1);
				return 1;
			}
			freehac(&hactmp1);
			if ( flg!=MMDATA_MPEGVIDEO ) {
				_stprintf( ss,TEXT("open %s alias myid"),fpath );
			} else {
				_stprintf( ss,TEXT("open %s type MPEGVIDEO alias myid"),fpath );
			}
			SendMCIT( ss );
			if (flg!=MMDATA_MCIVOICE) {
				if ( SendMCI( "where myid source" )==0 ) strcpy( avi_wh,res+4 );
				if ( a&16 ) {
					sprintf( avi_wh,"%d %d",avi_sx,avi_sy );
					avi_x=0;avi_y=0;
				}
				_stprintf( ss,TEXT("window myid handle %u"), (unsigned)HandleToUlong(avi_wnd) );
				SendMCIT( ss );
				_stprintf( ss,TEXT("put myid destination at %d %d %s"),avi_x,avi_y,chartoapichar(avi_wh,&hactmp1) );
				freehac(&hactmp1);
				SendMCIT( ss );
			}
			_tcscpy( ss,TEXT("play myid from 0") );
			break;

		case MMDATA_CDAUDIO:							// when "CD audio"

			SendMCI( "open cdaudio alias myid" );
			SendMCI( "set myid time format tmsf" );

			i=mmm->track;j=mmm->lasttrk;
			if ((i==j)||(a==3)) {
				_stprintf( ss,TEXT("play myid from %d"),i );
			} else {
				_stprintf( ss,TEXT("play myid from %d to %d"),i,i+1 );
			}
			break;
	}

	a&=15;
	if (a==1) _tcscat( ss,TEXT(" notify") );
	if (a==2) _tcscat( ss,TEXT(" wait") );
	SendMCIT(ss);
	curmus = num;

	if ( mmm->vol != 0 ) { SetVol( num, mmm->vol ); }

	return 0;
}

void MMMan::Notify( void )
{
	//		callback from windows message
	//			"MM_MCINOTIFY"
	//
	int a;
	a=curmus;
	if (curmus!=-1) {
		SendMCI("stop myid");
		SendMCI("close myid");
		curmus=-1;
	}
	Play( a );
}

void MMMan::GetInfo( int bank, char **fname, int *num, int *flag, int *opt )
{
	//		Get MMM info
	//
	MMM *mmm;
	mmm=&mem_snd[bank];
	*fname = mmm->fname;
	*opt=mmm->opt;
	*flag=mmm->flag;
	*num=mmm->num;
}

/*
int MMMan::GetBusy( void )
{
	//		wavĐ𒲂ׂ
	//
	if ( sndPlaySound( (LPCSTR)"",SND_NOSTOP|SND_NODEFAULT ) == FALSE ) {
		return 1;
	}
	return 0;
}
*/

void MMMan::SetVol( int num, int vol )
{
	MMM *mmm;
	int bank,flg;
	char ss[1024];
	bank = SearchBank( num );
	if ( bank < 0 ) return;

	mmm=&mem_snd[bank];
	mmm->vol = vol;
	if ( mmm->vol > 0 ) mmm->vol = 0;
	if ( mmm->vol < -1000 ) mmm->vol = -1000;

	flg=mmm->flag;
	switch(flg) {
	case MMDATA_INTWAVE:							// when "WAV"
		//
		break;
	case MMDATA_MCIVOICE:							// when "MID" file
	case MMDATA_MCIVIDEO:							// when "AVI" file
	case MMDATA_MPEGVIDEO:							// when "MPG" file
		if ( curmus != -1 ) {
			int mcivol;
			mcivol = mmm->vol + 1000;
			sprintf( ss,"setaudio myid volume to %d",mcivol );
			SendMCI( ss );
		}
		break;
	}
}

void MMMan::SetPan( int num, int pan )
{
	MMM *mmm;
	int bank,flg;
	bank = SearchBank( num );
	if ( bank < 0 ) return;

	mmm=&mem_snd[bank];
	flg=mmm->flag;
	switch(flg) {
	case MMDATA_INTWAVE:							// when "WAV"
		//
		break;
	}
}

int MMMan::GetStatus( int num, int infoid )
{
	MMM *mmm;
	int bank,flg;
	int res;
	bank = SearchBank( num );
	if ( bank < 0 ) return 0;

	mmm=&mem_snd[bank];
	flg=mmm->flag;
	res = 0;
	switch( infoid ) {
	case 0:
		res = mmm->opt;
		break;
	case 1:
		res = mmm->vol;
		break;
	case 2:
		res = mmm->pan;
		break;
	case 16:
		if (( flg == MMDATA_MCIVOICE )||( flg == MMDATA_MCIVIDEO )||( flg == MMDATA_MPEGVIDEO )) {
			if (curmus!=-1) res = 1;
		}
		break;
	}
	return res;
}

<|endoftext|>


<commit_before>#include <stdio.h>

#include <iostream>
#include <string>
#include <algorithm>

using namespace std;

int main () {
    return 0;
}
<commit_msg>add template.cc<commit_after>#include <stdio.h>
#include <string.h>

#include <iostream>
#include <string>
#include <algorithm>

using namespace std;

int main () {
    return 0;
}
<|endoftext|>


<commit_before>#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>

const int N = 1000;
void *x[N];

void *Thread1(void *) {
  for (int i = 0; i < N; i++) {
    fprintf(stderr, "%s %d\n", __FUNCTION__, i);
    free(x[i]);
  }
  return NULL;
}

void *Thread2(void *) {
  for (int i = 0; i < N; i++) {
    fprintf(stderr, "%s %d\n", __FUNCTION__, i);
    free(x[i]);
  }
  return NULL;
}

int main() {
  for (int i = 0; i < N; i++)
    x[i] = malloc(128);
  pthread_t t[2];
  pthread_create(&t[0], 0, Thread1, 0);
  pthread_create(&t[1], 0, Thread2, 0);
  pthread_join(t[0], 0);
  pthread_join(t[1], 0);
}
<commit_msg>[asan] fix lint<commit_after>#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>

const int N = 1000;
void *x[N];

void *Thread1(void *unused) {
  for (int i = 0; i < N; i++) {
    fprintf(stderr, "%s %d\n", __FUNCTION__, i);
    free(x[i]);
  }
  return NULL;
}

void *Thread2(void *unused) {
  for (int i = 0; i < N; i++) {
    fprintf(stderr, "%s %d\n", __FUNCTION__, i);
    free(x[i]);
  }
  return NULL;
}

int main() {
  for (int i = 0; i < N; i++)
    x[i] = malloc(128);
  pthread_t t[2];
  pthread_create(&t[0], 0, Thread1, 0);
  pthread_create(&t[1], 0, Thread2, 0);
  pthread_join(t[0], 0);
  pthread_join(t[1], 0);
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: xmlparse.hxx,v $
 *
 *  $Revision: 1.13 $
 *
 *  last change: $Author: kz $ $Date: 2008-03-06 12:34:17 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef BOOTSTRP_XMLPARSE_HXX
#define BOOTSTRP_XMLPARSE_HXX

#include <signal.h>
#ifdef SYSTEM_EXPAT
#include <expat.h>
#else
#include <external/expat/xmlparse.h>
#endif
#include <rtl/ustring.hxx>
#include <rtl/ustrbuf.hxx>
#include "tools/string.hxx"
#include "tools/list.hxx"
#define ENABLE_BYTESTRING_STREAM_OPERATORS
#include "tools/stream.hxx"
#include "tools/isofallback.hxx"
#include "export.hxx"
#include "xmlutil.hxx"

#include <fstream>
#include <iostream>

class XMLParentNode;
class XMLElement;

using namespace ::rtl;
using namespace std;

#include <hash_map> /* std::hashmap*/
#include <deque>    /* std::deque*/
#include <iterator> /* std::iterator*/
#include <list>     /* std::list*/
#include <vector>   /* std::vector*/
#define XML_NODE_TYPE_FILE          0x001
#define XML_NODE_TYPE_ELEMENT       0x002
#define XML_NODE_TYPE_DATA          0x003
#define XML_NODE_TYPE_COMMENT       0x004
#define XML_NODE_TYPE_DEFAULT       0x005
#define MAX_LANGUAGES               99

//#define TESTDRIVER        /* use xml2gsi testclass */
//-------------------------------------------------------------------------

/** Holds data of Attributes
 */
class XMLAttribute : public String
{
private:
    String sValue;

public:
    /// creates an attribute
    XMLAttribute(
        const String &rName,    // attributes name
        const String &rValue    // attributes data
    )
                : String( rName ), sValue( rValue ) {}

    /// getting value of an attribue
    const String &GetValue() { return sValue; }

    void setValue(const String &rValue){sValue=rValue;}

    /// returns true if two attributes are equal and have the same value
    BOOL IsEqual(
        const XMLAttribute &rAttribute  // the attribute which has to be equal
    )
    {
        return (( rAttribute == *this ) && ( rAttribute.sValue == sValue ));
    }
};

DECLARE_LIST( XMLAttributeList, XMLAttribute * )

//-------------------------------------------------------------------------

/** Virtual base to handle different kinds of XML nodes
 */
class XMLNode
{
protected:
    XMLNode() {}

public:
    virtual USHORT GetNodeType() = 0;
    virtual ~XMLNode() {}
};

//-------------------------------------------------------------------------

/** Virtual base to handle different kinds of child nodes
 */
class XMLChildNode : public XMLNode
{
private:
    XMLParentNode *pParent;

protected:
    XMLChildNode( XMLParentNode *pPar );
    XMLChildNode():pParent( NULL ){};
    XMLChildNode( const XMLChildNode& obj);
    XMLChildNode& operator=(const XMLChildNode& obj);
public:
    virtual USHORT GetNodeType() = 0;

    /// returns the parent of this node
    XMLParentNode *GetParent() { return pParent; }
    virtual ~XMLChildNode(){};
};

DECLARE_LIST( XMLChildNodeList, XMLChildNode * )

//-------------------------------------------------------------------------

/** Virtual base to handle different kinds of parent nodes
 */
class XMLData;

class XMLParentNode : public XMLChildNode
{
private:
    XMLChildNodeList *pChildList;
    static int dbgcnt;
    //int         nParentPos;
protected:
    XMLParentNode( XMLParentNode *pPar )
                : XMLChildNode( pPar ), pChildList( NULL )
              {
              }
    XMLParentNode(): pChildList(NULL){
    }
    /// Copyconstructor
    XMLParentNode( const XMLParentNode& );

    XMLParentNode& operator=(const XMLParentNode& obj);
    virtual ~XMLParentNode();

public:
    virtual USHORT GetNodeType() = 0;

    /// returns child list of this node
    XMLChildNodeList *GetChildList() { return pChildList; }

    /// adds a new child
    void AddChild(
        XMLChildNode *pChild    /// the new child
    );

    void AddChild(
        XMLChildNode *pChild , int pos  /// the new child
    );

    virtual int GetPosition( ByteString id );
    int RemoveChild( XMLElement *pRefElement );
    void RemoveAndDeleteAllChilds();

    /// returns a child element which matches the given one
    XMLElement *GetChildElement(
        XMLElement *pRefElement // the reference elelement
    );
};

//-------------------------------------------------------------------------

DECLARE_LIST( XMLStringList, XMLElement* )

/// Mapping numeric Language code <-> XML Element
typedef std::hash_map< ByteString ,XMLElement* , hashByteString,equalByteString > LangHashMap;

/// Mapping XML Element string identifier <-> Language Map
typedef std::hash_map<ByteString , LangHashMap* ,
                      hashByteString,equalByteString>                   XMLHashMap;

/// Mapping iso alpha string code <-> iso numeric code
typedef std::hash_map<ByteString, int, hashByteString,equalByteString>  HashMap;

/// Mapping XML tag names <-> have localizable strings
typedef std::hash_map<ByteString , BOOL ,
                      hashByteString,equalByteString>                   TagMap;

/** Holds information of a XML file, is root node of tree
 */

class XMLFile : public XMLParentNode
{
public:
    XMLFile() ;
    XMLFile(
                const String &rFileName // the file name, empty if created from memory stream
    );
    XMLFile( const XMLFile& obj ) ;
    ~XMLFile();

    ByteString* GetGroupID(std::deque<ByteString> &groupid);
    void        Print( XMLNode *pCur = NULL, USHORT nLevel = 0 );
    virtual void SearchL10NElements( XMLParentNode *pCur, int pos = 0 );
    void        Extract( XMLFile *pCur = NULL );
    void        View();
//  void static Signal_handler(int signo);//void*,oslSignalInfo * pInfo);
    void        showType(XMLParentNode* node);

    XMLHashMap* GetStrings(){return XMLStrings;}
    BOOL        Write( ByteString &rFilename );
    BOOL        Write( ofstream &rStream , XMLNode *pCur = NULL );

    bool        CheckExportStatus( XMLParentNode *pCur = NULL );// , int pos = 0 );

    XMLFile&    operator=(const XMLFile& obj);

    virtual USHORT  GetNodeType();

    /// returns file name
    const String &GetName() { return sFileName; }
    void          SetName( const String &rFilename ) { sFileName = rFilename; }
    const std::vector<ByteString> getOrder(){ return order; }

protected:
    // writes a string as UTF8 with dos line ends to a given stream
    void        WriteString( ofstream &rStream, const String &sString );

    // quotes the given text for writing to a file
    void        QuotHTML( String &rString );

    void        InsertL10NElement( XMLElement* pElement);

    // DATA
    String      sFileName;

    const ByteString ID,OLDREF,XML_LANG;

    TagMap      nodes_localize;
    XMLHashMap* XMLStrings;

    std::vector <ByteString> order;
};

/// An Utility class for XML
/// See RFC 3066 / #i8252# for ISO codes
class XMLUtil{

public:
    /// Quot the XML characters and replace \n \t
    static void         QuotHTML( String &rString );

    /// UnQuot the XML characters and restore \n \t
    static void         UnQuotHTML  ( String &rString );

    /// Return the numeric iso language code
    //USHORT                GetLangByIsoLang( const ByteString &rIsoLang );

    /// Return the alpha strings representation
    ByteString          GetIsoLangByIndex( USHORT nIndex );

    static XMLUtil&     Instance();
    ~XMLUtil();

    void         dump();

private:
    /// Mapping iso alpha string code <-> iso numeric code
    HashMap      lMap;

    /// Mapping iso numeric code      <-> iso alpha string code
    ByteString   isoArray[MAX_LANGUAGES];

    static void UnQuotData( String &rString );
    static void UnQuotTags( String &rString );

    XMLUtil();
    XMLUtil(const XMLUtil&);

};

//-------------------------------------------------------------------------

/** Hold information of an element node
 */
class XMLElement : public XMLParentNode
{
private:
    String sElementName;
    XMLAttributeList *pAttributes;
    ByteString   project,
                 filename,
                 id,
                 sOldRef,
                 resourceType,
                 languageId;
    int          nPos;

protected:
    void Print(XMLNode *pCur, OUStringBuffer& buffer , bool rootelement);
public:
    /// create a element node
    XMLElement(){}
    XMLElement(
        const String &rName,    // the element name
        XMLParentNode *Parent   // parent node of this element
    ):          XMLParentNode( Parent ),
                sElementName( rName ),
                pAttributes( NULL ),
                project(""),
                filename(""),
                id(""),
                sOldRef(""),
                resourceType(""),
                languageId(""),
                nPos(0)
                   {
                }
    ~XMLElement();
    XMLElement(const XMLElement&);

    XMLElement& operator=(const XMLElement& obj);
    /// returns node type XML_NODE_ELEMENT
    virtual USHORT GetNodeType();

    /// returns element name
    const String &GetName() { return sElementName; }

    /// returns list of attributes of this element
    XMLAttributeList *GetAttributeList() { return pAttributes; }

    /// adds a new attribute to this element, typically used by parser
    void AddAttribute( const String &rAttribute, const String &rValue );

    void ChangeLanguageTag( const String &rValue );
    // Return a ASCII String representation of this object
    OString ToOString();

    // Return a Unicode String representation of this object
    OUString ToOUString();

    bool    Equals(OUString refStr);

    /// returns a attribute
    XMLAttribute *GetAttribute(
        const String &rName // the attribute name
    );
    void SetProject         ( ByteString prj        ){ project = prj;        }
    void SetFileName        ( ByteString fn         ){ filename = fn;        }
    void SetId              ( ByteString theId      ){ id = theId;           }
    void SetResourceType    ( ByteString rt         ){ resourceType = rt;    }
    void SetLanguageId      ( ByteString lid        ){ languageId = lid;     }
    void SetPos             ( int nPos_in           ){ nPos = nPos_in;       }
    void SetOldRef          ( ByteString sOldRef_in ){ sOldRef = sOldRef_in; }

    virtual int        GetPos()         { return nPos;         }
    ByteString GetProject()     { return project;      }
    ByteString GetFileName()    { return filename;     }
    ByteString GetId()          { return id;           }
    ByteString GetOldref()      { return sOldRef;      }
    ByteString GetResourceType(){ return resourceType; }
    ByteString GetLanguageId()  { return languageId;   }

};
//-------------------------------------------------------------------------

/** Holds character data
 */
class XMLData : public XMLChildNode
{
private:
    String sData;
    bool   isNewCreated;

public:
    /// create a data node
    XMLData(
        const String &rData,    // the initial data
        XMLParentNode *Parent   // the parent node of this data, typically a element node
    )
                : XMLChildNode( Parent ), sData( rData ) , isNewCreated ( false ){}
    XMLData(
        const String &rData,    // the initial data
        XMLParentNode *Parent,  // the parent node of this data, typically a element node
        bool newCreated
    )
                : XMLChildNode( Parent ), sData( rData ) , isNewCreated ( newCreated ){}

    XMLData(const XMLData& obj);

    XMLData& operator=(const XMLData& obj);
    virtual USHORT GetNodeType();

    /// returns the data
    const String &GetData() { return sData; }

    bool isNew() { return isNewCreated; }
    /// adds new character data to the existing one
    void AddData(
        const String &rData // the new data
    );

};

//-------------------------------------------------------------------------

/** Holds comments
 */
class XMLComment : public XMLChildNode
{
private:
    String sComment;

public:
    /// create a comment node
    XMLComment(
        const String &rComment, // the comment
        XMLParentNode *Parent   // the parent node of this comemnt, typically a element node
    )
                : XMLChildNode( Parent ), sComment( rComment ) {}

    virtual USHORT GetNodeType();

    XMLComment( const XMLComment& obj );

    XMLComment& operator=(const XMLComment& obj);

    /// returns the comment
    const String &GetComment()  { return sComment; }
};

//-------------------------------------------------------------------------

/** Holds additional file content like those for which no handler exists
 */
class XMLDefault : public XMLChildNode
{
private:
    String sDefault;

public:
    /// create a comment node
    XMLDefault(
        const String &rDefault, // the comment
        XMLParentNode *Parent   // the parent node of this comemnt, typically a element node
    )
                : XMLChildNode( Parent ), sDefault( rDefault ) {}

    XMLDefault(const XMLDefault& obj);

    XMLDefault& operator=(const XMLDefault& obj);

    /// returns node type XML_NODE_TYPE_COMMENT
    virtual USHORT GetNodeType();

    /// returns the comment
    const String &GetDefault()  { return sDefault; }
};

//-------------------------------------------------------------------------

/** struct for error information, used by class SimpleXMLParser
 */
struct XMLError {
    XML_Error eCode;    // the error code
    ULONG nLine;        // error line number
    ULONG nColumn;      // error column number
    String sMessage;    // readable error message
};

//-------------------------------------------------------------------------

/** validating xml parser, creates a document tree with xml nodes
 */

class SimpleXMLParser
{
private:
    XML_Parser aParser;
    XMLError aErrorInformation;

    XMLFile *pXMLFile;
    XMLParentNode *pCurNode;
    XMLData *pCurData;

    static void StartElementHandler( void *userData, const XML_Char *name, const XML_Char **atts );
    static void EndElementHandler( void *userData, const XML_Char *name );
    static void CharacterDataHandler( void *userData, const XML_Char *s, int len );
    static void CommentHandler( void *userData, const XML_Char *data );
    static void DefaultHandler( void *userData, const XML_Char *s, int len );

    void StartElement( const XML_Char *name, const XML_Char **atts );
    void EndElement( const XML_Char *name );
    void CharacterData( const XML_Char *s, int len );
    void Comment( const XML_Char *data );
    void Default( const XML_Char *s, int len );

public:
    /// creates a new parser
    SimpleXMLParser();
    ~SimpleXMLParser();

    /// parse a file, returns NULL on criticall errors
    XMLFile *Execute(
        const String &rFileName,    // the file name
        XMLFile *pXMLFileIn         // the XMLFile
    );

    /// parse a memory stream, returns NULL on criticall errors
    XMLFile *Execute(
        SvMemoryStream *pStream // the stream
    );

    /// returns an error struct
    const XMLError &GetError() { return aErrorInformation; }
};

#endif
<commit_msg>INTEGRATION: CWS changefileheader (1.13.4); FILE MERGED 2008/03/28 15:41:58 rt 1.13.4.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: xmlparse.hxx,v $
 * $Revision: 1.14 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef BOOTSTRP_XMLPARSE_HXX
#define BOOTSTRP_XMLPARSE_HXX

#include <signal.h>
#ifdef SYSTEM_EXPAT
#include <expat.h>
#else
#include <external/expat/xmlparse.h>
#endif
#include <rtl/ustring.hxx>
#include <rtl/ustrbuf.hxx>
#include "tools/string.hxx"
#include "tools/list.hxx"
#define ENABLE_BYTESTRING_STREAM_OPERATORS
#include "tools/stream.hxx"
#include "tools/isofallback.hxx"
#include "export.hxx"
#include "xmlutil.hxx"

#include <fstream>
#include <iostream>

class XMLParentNode;
class XMLElement;

using namespace ::rtl;
using namespace std;

#include <hash_map> /* std::hashmap*/
#include <deque>    /* std::deque*/
#include <iterator> /* std::iterator*/
#include <list>     /* std::list*/
#include <vector>   /* std::vector*/
#define XML_NODE_TYPE_FILE          0x001
#define XML_NODE_TYPE_ELEMENT       0x002
#define XML_NODE_TYPE_DATA          0x003
#define XML_NODE_TYPE_COMMENT       0x004
#define XML_NODE_TYPE_DEFAULT       0x005
#define MAX_LANGUAGES               99

//#define TESTDRIVER        /* use xml2gsi testclass */
//-------------------------------------------------------------------------

/** Holds data of Attributes
 */
class XMLAttribute : public String
{
private:
    String sValue;

public:
    /// creates an attribute
    XMLAttribute(
        const String &rName,    // attributes name
        const String &rValue    // attributes data
    )
                : String( rName ), sValue( rValue ) {}

    /// getting value of an attribue
    const String &GetValue() { return sValue; }

    void setValue(const String &rValue){sValue=rValue;}

    /// returns true if two attributes are equal and have the same value
    BOOL IsEqual(
        const XMLAttribute &rAttribute  // the attribute which has to be equal
    )
    {
        return (( rAttribute == *this ) && ( rAttribute.sValue == sValue ));
    }
};

DECLARE_LIST( XMLAttributeList, XMLAttribute * )

//-------------------------------------------------------------------------

/** Virtual base to handle different kinds of XML nodes
 */
class XMLNode
{
protected:
    XMLNode() {}

public:
    virtual USHORT GetNodeType() = 0;
    virtual ~XMLNode() {}
};

//-------------------------------------------------------------------------

/** Virtual base to handle different kinds of child nodes
 */
class XMLChildNode : public XMLNode
{
private:
    XMLParentNode *pParent;

protected:
    XMLChildNode( XMLParentNode *pPar );
    XMLChildNode():pParent( NULL ){};
    XMLChildNode( const XMLChildNode& obj);
    XMLChildNode& operator=(const XMLChildNode& obj);
public:
    virtual USHORT GetNodeType() = 0;

    /// returns the parent of this node
    XMLParentNode *GetParent() { return pParent; }
    virtual ~XMLChildNode(){};
};

DECLARE_LIST( XMLChildNodeList, XMLChildNode * )

//-------------------------------------------------------------------------

/** Virtual base to handle different kinds of parent nodes
 */
class XMLData;

class XMLParentNode : public XMLChildNode
{
private:
    XMLChildNodeList *pChildList;
    static int dbgcnt;
    //int         nParentPos;
protected:
    XMLParentNode( XMLParentNode *pPar )
                : XMLChildNode( pPar ), pChildList( NULL )
              {
              }
    XMLParentNode(): pChildList(NULL){
    }
    /// Copyconstructor
    XMLParentNode( const XMLParentNode& );

    XMLParentNode& operator=(const XMLParentNode& obj);
    virtual ~XMLParentNode();

public:
    virtual USHORT GetNodeType() = 0;

    /// returns child list of this node
    XMLChildNodeList *GetChildList() { return pChildList; }

    /// adds a new child
    void AddChild(
        XMLChildNode *pChild    /// the new child
    );

    void AddChild(
        XMLChildNode *pChild , int pos  /// the new child
    );

    virtual int GetPosition( ByteString id );
    int RemoveChild( XMLElement *pRefElement );
    void RemoveAndDeleteAllChilds();

    /// returns a child element which matches the given one
    XMLElement *GetChildElement(
        XMLElement *pRefElement // the reference elelement
    );
};

//-------------------------------------------------------------------------

DECLARE_LIST( XMLStringList, XMLElement* )

/// Mapping numeric Language code <-> XML Element
typedef std::hash_map< ByteString ,XMLElement* , hashByteString,equalByteString > LangHashMap;

/// Mapping XML Element string identifier <-> Language Map
typedef std::hash_map<ByteString , LangHashMap* ,
                      hashByteString,equalByteString>                   XMLHashMap;

/// Mapping iso alpha string code <-> iso numeric code
typedef std::hash_map<ByteString, int, hashByteString,equalByteString>  HashMap;

/// Mapping XML tag names <-> have localizable strings
typedef std::hash_map<ByteString , BOOL ,
                      hashByteString,equalByteString>                   TagMap;

/** Holds information of a XML file, is root node of tree
 */

class XMLFile : public XMLParentNode
{
public:
    XMLFile() ;
    XMLFile(
                const String &rFileName // the file name, empty if created from memory stream
    );
    XMLFile( const XMLFile& obj ) ;
    ~XMLFile();

    ByteString* GetGroupID(std::deque<ByteString> &groupid);
    void        Print( XMLNode *pCur = NULL, USHORT nLevel = 0 );
    virtual void SearchL10NElements( XMLParentNode *pCur, int pos = 0 );
    void        Extract( XMLFile *pCur = NULL );
    void        View();
//  void static Signal_handler(int signo);//void*,oslSignalInfo * pInfo);
    void        showType(XMLParentNode* node);

    XMLHashMap* GetStrings(){return XMLStrings;}
    BOOL        Write( ByteString &rFilename );
    BOOL        Write( ofstream &rStream , XMLNode *pCur = NULL );

    bool        CheckExportStatus( XMLParentNode *pCur = NULL );// , int pos = 0 );

    XMLFile&    operator=(const XMLFile& obj);

    virtual USHORT  GetNodeType();

    /// returns file name
    const String &GetName() { return sFileName; }
    void          SetName( const String &rFilename ) { sFileName = rFilename; }
    const std::vector<ByteString> getOrder(){ return order; }

protected:
    // writes a string as UTF8 with dos line ends to a given stream
    void        WriteString( ofstream &rStream, const String &sString );

    // quotes the given text for writing to a file
    void        QuotHTML( String &rString );

    void        InsertL10NElement( XMLElement* pElement);

    // DATA
    String      sFileName;

    const ByteString ID,OLDREF,XML_LANG;

    TagMap      nodes_localize;
    XMLHashMap* XMLStrings;

    std::vector <ByteString> order;
};

/// An Utility class for XML
/// See RFC 3066 / #i8252# for ISO codes
class XMLUtil{

public:
    /// Quot the XML characters and replace \n \t
    static void         QuotHTML( String &rString );

    /// UnQuot the XML characters and restore \n \t
    static void         UnQuotHTML  ( String &rString );

    /// Return the numeric iso language code
    //USHORT                GetLangByIsoLang( const ByteString &rIsoLang );

    /// Return the alpha strings representation
    ByteString          GetIsoLangByIndex( USHORT nIndex );

    static XMLUtil&     Instance();
    ~XMLUtil();

    void         dump();

private:
    /// Mapping iso alpha string code <-> iso numeric code
    HashMap      lMap;

    /// Mapping iso numeric code      <-> iso alpha string code
    ByteString   isoArray[MAX_LANGUAGES];

    static void UnQuotData( String &rString );
    static void UnQuotTags( String &rString );

    XMLUtil();
    XMLUtil(const XMLUtil&);

};

//-------------------------------------------------------------------------

/** Hold information of an element node
 */
class XMLElement : public XMLParentNode
{
private:
    String sElementName;
    XMLAttributeList *pAttributes;
    ByteString   project,
                 filename,
                 id,
                 sOldRef,
                 resourceType,
                 languageId;
    int          nPos;

protected:
    void Print(XMLNode *pCur, OUStringBuffer& buffer , bool rootelement);
public:
    /// create a element node
    XMLElement(){}
    XMLElement(
        const String &rName,    // the element name
        XMLParentNode *Parent   // parent node of this element
    ):          XMLParentNode( Parent ),
                sElementName( rName ),
                pAttributes( NULL ),
                project(""),
                filename(""),
                id(""),
                sOldRef(""),
                resourceType(""),
                languageId(""),
                nPos(0)
                   {
                }
    ~XMLElement();
    XMLElement(const XMLElement&);

    XMLElement& operator=(const XMLElement& obj);
    /// returns node type XML_NODE_ELEMENT
    virtual USHORT GetNodeType();

    /// returns element name
    const String &GetName() { return sElementName; }

    /// returns list of attributes of this element
    XMLAttributeList *GetAttributeList() { return pAttributes; }

    /// adds a new attribute to this element, typically used by parser
    void AddAttribute( const String &rAttribute, const String &rValue );

    void ChangeLanguageTag( const String &rValue );
    // Return a ASCII String representation of this object
    OString ToOString();

    // Return a Unicode String representation of this object
    OUString ToOUString();

    bool    Equals(OUString refStr);

    /// returns a attribute
    XMLAttribute *GetAttribute(
        const String &rName // the attribute name
    );
    void SetProject         ( ByteString prj        ){ project = prj;        }
    void SetFileName        ( ByteString fn         ){ filename = fn;        }
    void SetId              ( ByteString theId      ){ id = theId;           }
    void SetResourceType    ( ByteString rt         ){ resourceType = rt;    }
    void SetLanguageId      ( ByteString lid        ){ languageId = lid;     }
    void SetPos             ( int nPos_in           ){ nPos = nPos_in;       }
    void SetOldRef          ( ByteString sOldRef_in ){ sOldRef = sOldRef_in; }

    virtual int        GetPos()         { return nPos;         }
    ByteString GetProject()     { return project;      }
    ByteString GetFileName()    { return filename;     }
    ByteString GetId()          { return id;           }
    ByteString GetOldref()      { return sOldRef;      }
    ByteString GetResourceType(){ return resourceType; }
    ByteString GetLanguageId()  { return languageId;   }

};
//-------------------------------------------------------------------------

/** Holds character data
 */
class XMLData : public XMLChildNode
{
private:
    String sData;
    bool   isNewCreated;

public:
    /// create a data node
    XMLData(
        const String &rData,    // the initial data
        XMLParentNode *Parent   // the parent node of this data, typically a element node
    )
                : XMLChildNode( Parent ), sData( rData ) , isNewCreated ( false ){}
    XMLData(
        const String &rData,    // the initial data
        XMLParentNode *Parent,  // the parent node of this data, typically a element node
        bool newCreated
    )
                : XMLChildNode( Parent ), sData( rData ) , isNewCreated ( newCreated ){}

    XMLData(const XMLData& obj);

    XMLData& operator=(const XMLData& obj);
    virtual USHORT GetNodeType();

    /// returns the data
    const String &GetData() { return sData; }

    bool isNew() { return isNewCreated; }
    /// adds new character data to the existing one
    void AddData(
        const String &rData // the new data
    );

};

//-------------------------------------------------------------------------

/** Holds comments
 */
class XMLComment : public XMLChildNode
{
private:
    String sComment;

public:
    /// create a comment node
    XMLComment(
        const String &rComment, // the comment
        XMLParentNode *Parent   // the parent node of this comemnt, typically a element node
    )
                : XMLChildNode( Parent ), sComment( rComment ) {}

    virtual USHORT GetNodeType();

    XMLComment( const XMLComment& obj );

    XMLComment& operator=(const XMLComment& obj);

    /// returns the comment
    const String &GetComment()  { return sComment; }
};

//-------------------------------------------------------------------------

/** Holds additional file content like those for which no handler exists
 */
class XMLDefault : public XMLChildNode
{
private:
    String sDefault;

public:
    /// create a comment node
    XMLDefault(
        const String &rDefault, // the comment
        XMLParentNode *Parent   // the parent node of this comemnt, typically a element node
    )
                : XMLChildNode( Parent ), sDefault( rDefault ) {}

    XMLDefault(const XMLDefault& obj);

    XMLDefault& operator=(const XMLDefault& obj);

    /// returns node type XML_NODE_TYPE_COMMENT
    virtual USHORT GetNodeType();

    /// returns the comment
    const String &GetDefault()  { return sDefault; }
};

//-------------------------------------------------------------------------

/** struct for error information, used by class SimpleXMLParser
 */
struct XMLError {
    XML_Error eCode;    // the error code
    ULONG nLine;        // error line number
    ULONG nColumn;      // error column number
    String sMessage;    // readable error message
};

//-------------------------------------------------------------------------

/** validating xml parser, creates a document tree with xml nodes
 */

class SimpleXMLParser
{
private:
    XML_Parser aParser;
    XMLError aErrorInformation;

    XMLFile *pXMLFile;
    XMLParentNode *pCurNode;
    XMLData *pCurData;

    static void StartElementHandler( void *userData, const XML_Char *name, const XML_Char **atts );
    static void EndElementHandler( void *userData, const XML_Char *name );
    static void CharacterDataHandler( void *userData, const XML_Char *s, int len );
    static void CommentHandler( void *userData, const XML_Char *data );
    static void DefaultHandler( void *userData, const XML_Char *s, int len );

    void StartElement( const XML_Char *name, const XML_Char **atts );
    void EndElement( const XML_Char *name );
    void CharacterData( const XML_Char *s, int len );
    void Comment( const XML_Char *data );
    void Default( const XML_Char *s, int len );

public:
    /// creates a new parser
    SimpleXMLParser();
    ~SimpleXMLParser();

    /// parse a file, returns NULL on criticall errors
    XMLFile *Execute(
        const String &rFileName,    // the file name
        XMLFile *pXMLFileIn         // the XMLFile
    );

    /// parse a memory stream, returns NULL on criticall errors
    XMLFile *Execute(
        SvMemoryStream *pStream // the stream
    );

    /// returns an error struct
    const XMLError &GetError() { return aErrorInformation; }
};

#endif
<|endoftext|>


<commit_before>#define DEBUG 1
/**
 * File    : E3.cpp
 * Author  : Kazune Takahashi
 * Created : 2019/9/2 0:33:07
 * Powered by Visual Studio Code
 */
#include <iostream>
#include <iomanip>
#include <algorithm>
#include <vector>
#include <string>
#include <complex>
#include <tuple>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <bitset>
#include <functional>
#include <random>
#include <chrono>
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
using namespace std;
#define maxs(x, y) (x = max(x, y))
#define mins(x, y) (x = min(x, y))
using ll = long long;
class mint
{
public:
  static ll MOD;
  ll x;
  mint() : x(0) {}
  mint(ll x) : x(x % MOD) {}
  mint operator-() const { return x ? MOD - x : 0; }
  mint &operator+=(const mint &a)
  {
    if ((x += a.x) >= MOD)
    {
      x -= MOD;
    }
    return *this;
  }
  mint &operator-=(const mint &a) { return *this += -a; }
  mint &operator*=(const mint &a)
  {
    (x *= a.x) %= MOD;
    return *this;
  }
  mint &operator/=(const mint &a)
  {
    mint b{a};
    return *this *= b.power(MOD - 2);
  }
  mint operator+(const mint &a) const { return mint(*this) += a; }
  mint operator-(const mint &a) const { return mint(*this) -= a; }
  mint operator*(const mint &a) const { return mint(*this) *= a; }
  mint operator/(const mint &a) const { return mint(*this) /= a; }
  bool operator<(const mint &a) const { return x < a.x; }
  bool operator==(const mint &a) const { return x == a.x; }
  const mint power(ll N)
  {
    if (N == 0)
    {
      return 1;
    }
    else if (N % 2 == 1)
    {
      return *this * power(N - 1);
    }
    else
    {
      mint half = power(N / 2);
      return half * half;
    }
  }
};
ll mint::MOD = 1e9 + 7;
istream &operator>>(istream &stream, mint &a) { return stream >> a.x; }
ostream &operator<<(ostream &stream, const mint &a) { return stream << a.x; }
class combination
{
public:
  vector<mint> inv, fact, factinv;
  static int MAX_SIZE;
  combination() : inv(MAX_SIZE), fact(MAX_SIZE), factinv(MAX_SIZE)
  {
    inv[1] = 1;
    for (auto i = 2; i < MAX_SIZE; i++)
    {
      inv[i] = (-inv[mint::MOD % i]) * (mint::MOD / i);
    }
    fact[0] = factinv[0] = 1;
    for (auto i = 1; i < MAX_SIZE; i++)
    {
      fact[i] = mint(i) * fact[i - 1];
      factinv[i] = inv[i] * factinv[i - 1];
    }
  }
  mint operator()(int n, int k)
  {
    if (n >= 0 && k >= 0 && n - k >= 0)
    {
      return fact[n] * factinv[k] * factinv[n - k];
    }
    return 0;
  }
};
int combination::MAX_SIZE = 3000010;
ll gcd(ll x, ll y) { return y ? gcd(y, x % y) : x; }
// constexpr double epsilon = 1e-10;
// constexpr ll infty = 1000000000000000LL;
// constexpr int dx[4] = {1, 0, -1, 0};
// constexpr int dy[4] = {0, 1, 0, -1};
void Yes()
{
  cout << "Yes" << endl;
  exit(0);
}
void No()
{
  cout << "-1" << endl;
  exit(0);
}

using point = tuple<int, int>;

point make_point(int i, int j)
{
  if (i > j)
  {
    swap(i, j);
  }
  return point{i, j};
}

map<point, int> DP;
map<point, vector<point>> V;
set<point> Y;

int dfs(point p)
{
  if (DP.find(p) != DP.end())
  {
    return DP[p];
  }
  DP[p] = 0;
  if (Y.find(p) != Y.end())
  {
    No();
  }
  Y.insert(p);
  for (auto e : V[p])
  {
    maxs(DP[p], dfs(e) + 1);
  }
  Y.erase(p);
  return DP[p];
}

int main()
{
  int N;
  cin >> N;
  vector<vector<int>> A(N, vector<int>(N - 1));
  for (auto i = 0; i < N; i++)
  {
    for (auto j = 0; j < N - 1; j++)
    {
      cin >> A[i][j];
      A[i][j]--;
    }
  }
  for (auto i = 0; i < N; i++)
  {
    for (auto j = 1; j < N - 1; j++)
    {
      point from{make_point(i, A[i][j - 1])};
      point to{make_point(i, A[i][j - 1])};
      V[to].push_back(from);
    }
  }
  for (auto i = 0; i < N; i++)
  {
    for (auto j = i + 1; j < N; j++)
    {
      dfs(point{i, j});
    }
  }
  int ans{0};
  for (auto e : DP)
  {
    maxs(ans, e.second);
  }
  cout << ans << endl;
}<commit_msg>tried E3.cpp to 'E'<commit_after>#define DEBUG 1
/**
 * File    : E3.cpp
 * Author  : Kazune Takahashi
 * Created : 2019/9/2 0:33:07
 * Powered by Visual Studio Code
 */
#include <iostream>
#include <iomanip>
#include <algorithm>
#include <vector>
#include <string>
#include <complex>
#include <tuple>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <bitset>
#include <functional>
#include <random>
#include <chrono>
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
using namespace std;
#define maxs(x, y) (x = max(x, y))
#define mins(x, y) (x = min(x, y))
using ll = long long;
class mint
{
public:
  static ll MOD;
  ll x;
  mint() : x(0) {}
  mint(ll x) : x(x % MOD) {}
  mint operator-() const { return x ? MOD - x : 0; }
  mint &operator+=(const mint &a)
  {
    if ((x += a.x) >= MOD)
    {
      x -= MOD;
    }
    return *this;
  }
  mint &operator-=(const mint &a) { return *this += -a; }
  mint &operator*=(const mint &a)
  {
    (x *= a.x) %= MOD;
    return *this;
  }
  mint &operator/=(const mint &a)
  {
    mint b{a};
    return *this *= b.power(MOD - 2);
  }
  mint operator+(const mint &a) const { return mint(*this) += a; }
  mint operator-(const mint &a) const { return mint(*this) -= a; }
  mint operator*(const mint &a) const { return mint(*this) *= a; }
  mint operator/(const mint &a) const { return mint(*this) /= a; }
  bool operator<(const mint &a) const { return x < a.x; }
  bool operator==(const mint &a) const { return x == a.x; }
  const mint power(ll N)
  {
    if (N == 0)
    {
      return 1;
    }
    else if (N % 2 == 1)
    {
      return *this * power(N - 1);
    }
    else
    {
      mint half = power(N / 2);
      return half * half;
    }
  }
};
ll mint::MOD = 1e9 + 7;
istream &operator>>(istream &stream, mint &a) { return stream >> a.x; }
ostream &operator<<(ostream &stream, const mint &a) { return stream << a.x; }
class combination
{
public:
  vector<mint> inv, fact, factinv;
  static int MAX_SIZE;
  combination() : inv(MAX_SIZE), fact(MAX_SIZE), factinv(MAX_SIZE)
  {
    inv[1] = 1;
    for (auto i = 2; i < MAX_SIZE; i++)
    {
      inv[i] = (-inv[mint::MOD % i]) * (mint::MOD / i);
    }
    fact[0] = factinv[0] = 1;
    for (auto i = 1; i < MAX_SIZE; i++)
    {
      fact[i] = mint(i) * fact[i - 1];
      factinv[i] = inv[i] * factinv[i - 1];
    }
  }
  mint operator()(int n, int k)
  {
    if (n >= 0 && k >= 0 && n - k >= 0)
    {
      return fact[n] * factinv[k] * factinv[n - k];
    }
    return 0;
  }
};
int combination::MAX_SIZE = 3000010;
ll gcd(ll x, ll y) { return y ? gcd(y, x % y) : x; }
// constexpr double epsilon = 1e-10;
// constexpr ll infty = 1000000000000000LL;
// constexpr int dx[4] = {1, 0, -1, 0};
// constexpr int dy[4] = {0, 1, 0, -1};
void Yes()
{
  cout << "Yes" << endl;
  exit(0);
}
void No()
{
  cout << "-1" << endl;
  exit(0);
}

using point = tuple<int, int>;

ostream &operator<<(ostream &os, point p)
{
  return os << "{" << get<0>(p) << ", " << get<1>(p) << "}";
}

point make_point(int i, int j)
{
  if (i > j)
  {
    swap(i, j);
  }
  return point{i, j};
}

map<point, int> DP;
map<point, vector<point>> V;
set<point> Y;

int dfs(point p)
{
#if DEBUG == 1
  cerr << "p = " << p << endl;
#endif
  if (DP.find(p) != DP.end())
  {
    return DP[p];
  }
  DP[p] = 0;
  if (Y.find(p) != Y.end())
  {
    No();
  }
  Y.insert(p);
  for (auto e : V[p])
  {
    maxs(DP[p], dfs(e) + 1);
  }
  Y.erase(p);
  return DP[p];
}

int main()
{
  int N;
  cin >> N;
  vector<vector<int>> A(N, vector<int>(N - 1));
  for (auto i = 0; i < N; i++)
  {
    for (auto j = 0; j < N - 1; j++)
    {
      cin >> A[i][j];
      A[i][j]--;
    }
  }
  for (auto i = 0; i < N; i++)
  {
    for (auto j = 1; j < N - 1; j++)
    {
      point from{make_point(i, A[i][j - 1])};
      point to{make_point(i, A[i][j - 1])};
      V[to].push_back(from);
    }
  }
  for (auto i = 0; i < N; i++)
  {
    for (auto j = i + 1; j < N; j++)
    {
      dfs(point{i, j});
    }
  }
  int ans{0};
  for (auto e : DP)
  {
    maxs(ans, e.second);
  }
  cout << ans << endl;
}<|endoftext|>


<commit_before>#include "AudioProcessor.h"

#include "AudioDevice.h"

#include <QAudioOutput>

extern "C" {
#include "gba-thread.h"
}

using namespace QGBA;

AudioProcessor::AudioProcessor(QObject* parent)
	: QObject(parent)
	, m_audioOutput(nullptr)
	, m_device(nullptr)
{
}

void AudioProcessor::setInput(GBAThread* input) {
	m_context = input;
	if (m_device) {
		m_device->setInput(input);
		if (m_audioOutput) {
			m_device->setFormat(m_audioOutput->format());
		}
	}
}

void AudioProcessor::start() {
	if (!m_device) {
		m_device = new AudioDevice(this);
	}

	if (!m_audioOutput) {
		QAudioFormat format;
		format.setSampleRate(44100);
		format.setChannelCount(2);
		format.setSampleSize(16);
		format.setCodec("audio/pcm");
		format.setByteOrder(QAudioFormat::LittleEndian);
		format.setSampleType(QAudioFormat::SignedInt);

		m_audioOutput = new QAudioOutput(format, this);
	}

	m_device->setInput(m_context);
	m_device->setFormat(m_audioOutput->format());
	m_audioOutput->setBufferSize(m_context->audioBuffers * 4);

	m_audioOutput->start(m_device);
}

void AudioProcessor::pause() {
	m_audioOutput->stop();
}

void AudioProcessor::setBufferSamples(int samples) {
	QAudioFormat format = m_audioOutput->format();
	m_audioOutput->setBufferSize(samples * format.channelCount() * format.sampleSize() / 8);
}
<commit_msg>Only try to stop audio output if there is an audio output device<commit_after>#include "AudioProcessor.h"

#include "AudioDevice.h"

#include <QAudioOutput>

extern "C" {
#include "gba-thread.h"
}

using namespace QGBA;

AudioProcessor::AudioProcessor(QObject* parent)
	: QObject(parent)
	, m_audioOutput(nullptr)
	, m_device(nullptr)
{
}

void AudioProcessor::setInput(GBAThread* input) {
	m_context = input;
	if (m_device) {
		m_device->setInput(input);
		if (m_audioOutput) {
			m_device->setFormat(m_audioOutput->format());
		}
	}
}

void AudioProcessor::start() {
	if (!m_device) {
		m_device = new AudioDevice(this);
	}

	if (!m_audioOutput) {
		QAudioFormat format;
		format.setSampleRate(44100);
		format.setChannelCount(2);
		format.setSampleSize(16);
		format.setCodec("audio/pcm");
		format.setByteOrder(QAudioFormat::LittleEndian);
		format.setSampleType(QAudioFormat::SignedInt);

		m_audioOutput = new QAudioOutput(format, this);
	}

	m_device->setInput(m_context);
	m_device->setFormat(m_audioOutput->format());
	m_audioOutput->setBufferSize(m_context->audioBuffers * 4);

	m_audioOutput->start(m_device);
}

void AudioProcessor::pause() {
	if (m_audioOutput) {
		m_audioOutput->stop();
	}
}

void AudioProcessor::setBufferSamples(int samples) {
	QAudioFormat format = m_audioOutput->format();
	m_audioOutput->setBufferSize(samples * format.channelCount() * format.sampleSize() / 8);
}
<|endoftext|>


<commit_before>#include <algorithm>
#include <cstring>
#include <limits>
#include <memory>

#include <android/log.h>

#include <boost/format.hpp>
#include <boost/utility.hpp>

#include <tbb/blocked_range2d.h>
#include <tbb/parallel_for.h>
#include <tbb/task_scheduler_init.h>

#include "body_parts_recognizer.h"
#include "rgbd_image.h"
#include "sources.h"
#include "stopwatch.h"

const Depth BACKGROUND_DEPTH = std::numeric_limits<Depth>::max();

struct DepthImage
{
private:

  unsigned width, height;
  std::vector<Depth> depths;

public:

  DepthImage(const RGBDImage & image)
    : width(image.width), height(image.height), depths(width * height)
  {
    for (std::size_t i = 0; i < depths.size(); ++i)
      depths[i] = image.pixels[i].d == 0 ? BACKGROUND_DEPTH : image.pixels[i].d; // we consider 0 to be invalid depth
  }

  void
  applyThreshold(int threshold)
  {
    Depth min_depth = *std::min_element(depths.begin (), depths.end ());

    for (std::size_t i = 0; i < depths.size (); ++i)
      depths[i] = depths[i] <= min_depth + threshold ? depths[i] : BACKGROUND_DEPTH;
  }

  Depth
  getDepth(int x, int y) const
  {
    if (x < 0 || x >= int (width) || y < 0 || y >= int (height))
      return BACKGROUND_DEPTH;

    return depths[x + width * y];
  }

  unsigned getWidth() const { return width; }
  unsigned getHeight() const { return height; }
};

struct DecisionTreeCPU
{
  tbb::task_scheduler_init tbb_init;

  struct Offsets
  {
    boost::int16_t du1, dv1, du2, dv2;
  };

  struct Node
  {
    Offsets offsets;
    boost::int16_t threshold;
  };

  boost::uint16_t depth;
  std::vector<Node> nodes;
  std::vector<Label> leaves;

  DecisionTreeCPU(const char * data)
  {
    std::memcpy (&depth, data, sizeof depth);
    data += sizeof depth;

    nodes.resize ((1 << depth) - 1);
    std::memcpy (&nodes.front (), data, nodes.size () * sizeof (Node));
    data += nodes.size () * sizeof (Node);

    leaves.resize (1 << depth);
    std::memcpy (&leaves.front (), data, leaves.size () * sizeof (Label));
    data += leaves.size () * sizeof (Label);
  }

  Label
  walk(const DepthImage & image, int x, int y) const
  {
    unsigned nid = 0;
    Depth d0 = image.getDepth(x, y);
    float scale = 1000.0f / d0;

    for(int node_depth = 0; node_depth < depth; ++node_depth)
    {
      const Node & node = nodes[nid];

      Depth d1 = image.getDepth (x + node.offsets.du1 * scale, y + node.offsets.dv1 * scale);
      Depth d2 = image.getDepth (x + node.offsets.du2 * scale, y + node.offsets.dv2 * scale);

      int feature = int (d1) - int (d2);

      if (feature > node.threshold)
        nid = nid * 2 + 2;
      else
        nid = nid * 2 + 1;
    }

    return leaves[nid - nodes.size()];
  }

  struct WalkHelper
  {
  private:
    const DecisionTreeCPU & tree;
    const DepthImage & image;
    std::vector<Label> & labels;

  public:
    WalkHelper(const DecisionTreeCPU & tree, const DepthImage & image, std::vector<Label> & labels)
      : tree(tree), image(image), labels(labels)
    {
    }

    void
    operator () (const tbb::blocked_range2d<unsigned> & range) const
    {
      for (unsigned y = range.rows().begin(); y < range.rows().end(); ++y)
        for (unsigned x = range.cols().begin(); x < range.cols().end(); ++x)
          labels[x + y * image.getWidth()] = image.getDepth(x, y) == BACKGROUND_DEPTH ?
                Labels::Background : tree.walk(image, x, y);
    }
  };

  void
  eval(const DepthImage & image, std::vector<Label> & labels) const
  {
    tbb::parallel_for(
          tbb::blocked_range2d<unsigned>(0, image.getHeight(), 0, image.getWidth()),
          WalkHelper(*this, image, labels)
    );
  }
};

int maxElementNoTie(int num, unsigned * elements)
{
  int max_element = 0;
  unsigned max = elements[max_element];

  for (int i = 1; i < num; ++i)
  {
    unsigned val = elements[i];
    if (max < val) { max_element = i; max = val; }
    else if (max == val) { max_element = -1; }
  }

  return max_element;
}

struct ConsensusHelper
{
private:
  const std::vector<std::vector<Label> > & multi_labels;
  std::vector<Label> & labels;
  const DepthImage & depth_image;

public:
  ConsensusHelper(
      const std::vector<std::vector<Label> > & multi_labels,
      std::vector<Label> & labels,
      const DepthImage & depth_image
  )
    : multi_labels(multi_labels), labels(labels), depth_image(depth_image)
  {
  }

  void operator ()(const tbb::blocked_range2d<unsigned> & range) const
  {
    for (unsigned y = range.rows().begin(); y < range.rows().end(); ++y)
      for (unsigned x = range.cols().begin(); x < range.cols().end(); ++x)
      {
        std::size_t i = x + y * depth_image.getWidth();

        bool background = true;
        for (std::size_t ti = 0; ti < multi_labels.size (); ++ti)
          if (multi_labels[ti][i] != Labels::Background) background = false;

        if (background)
        {
          labels[i] = Labels::Background;
          continue;
        }

        unsigned bins[Labels::NUM_LABELS] = { 0 };

        for (std::size_t ti = 0; ti < multi_labels.size (); ++ti)
          ++bins[multi_labels[ti][i]];

        int consensus = maxElementNoTie(Labels::NUM_LABELS, bins);

        if (consensus == -1)
        {
          std::fill (bins, bins + Labels::NUM_LABELS, 0);
          Depth d = depth_image.getDepth (x, y);

          for (int off_x = -1; off_x <= 1; ++off_x)
            for (int off_y = -1; off_y <= 1; ++off_y)
            {
              Depth off_d = depth_image.getDepth (x + off_x, y + off_y);

              if (std::abs (d - off_d) < 50)
                for (std::size_t ti = 0; ti < multi_labels.size (); ++ti)
                  ++bins[multi_labels[ti][i]];
            }

          labels[i] = std::max_element (bins, bins + Labels::NUM_LABELS) - bins;
        }
        else
        {
          labels[i] = consensus;
        }
      }
  }
};

BodyPartsRecognizer::BodyPartsRecognizer(std::size_t num_trees, const char * trees[])
{
  this->trees.resize(num_trees);

  for (std::size_t i = 0; i < num_trees; ++i)
    this->trees[i].reset(new Tree(trees[i]));

#if GPU_CONSENSUS
  this->consensus_finder.reset(new ConsensusFinderGPU(num_trees));
#endif
}

void
BodyPartsRecognizer::recognize(const RGBDImage & image, std::vector<Label> & labels)
{
  labels.clear ();
  labels.resize (image.width * image.height);

  DepthImage depth_image (image);

  Stopwatch watch_threshold;

  depth_image.applyThreshold (500);

  __android_log_print(ANDROID_LOG_INFO, "BPR", "Thresholding: %d ms", watch_threshold.elapsedMs());

  std::vector<std::vector<Label> > multi_labels (trees.size ());

  for (std::size_t ti = 0; ti < trees.size (); ++ti)
  {
    Stopwatch watch_evaluation;

    multi_labels[ti].resize (labels.size ());
    trees[ti]->eval (depth_image, multi_labels[ti]);

    __android_log_print(ANDROID_LOG_INFO, "BPR", "Evaluating tree %d: %d ms", ti, watch_evaluation.elapsedMs());
  }

  Stopwatch watch_consensus;

  tbb::parallel_for(
        tbb::blocked_range2d<unsigned>(0, depth_image.getHeight(), 0, depth_image.getWidth()),
        ConsensusHelper(multi_labels, labels, depth_image)
  );

  __android_log_print(ANDROID_LOG_INFO, "BPR", "Finding consensus: %d ms", watch_consensus.elapsedMs());
}
<commit_msg>Implemented a simple mode-based filter for labels.<commit_after>#include <algorithm>
#include <cstring>
#include <limits>
#include <memory>

#include <android/log.h>

#include <boost/format.hpp>
#include <boost/utility.hpp>

#include <tbb/blocked_range2d.h>
#include <tbb/parallel_for.h>
#include <tbb/task_scheduler_init.h>

#include "body_parts_recognizer.h"
#include "rgbd_image.h"
#include "sources.h"
#include "stopwatch.h"

const Depth BACKGROUND_DEPTH = std::numeric_limits<Depth>::max();

struct DepthImage
{
private:

  unsigned width, height;
  std::vector<Depth> depths;

public:

  DepthImage(const RGBDImage & image)
    : width(image.width), height(image.height), depths(width * height)
  {
    for (std::size_t i = 0; i < depths.size(); ++i)
      depths[i] = image.pixels[i].d == 0 ? BACKGROUND_DEPTH : image.pixels[i].d; // we consider 0 to be invalid depth
  }

  void
  applyThreshold(int threshold)
  {
    Depth min_depth = *std::min_element(depths.begin (), depths.end ());

    for (std::size_t i = 0; i < depths.size (); ++i)
      depths[i] = depths[i] <= min_depth + threshold ? depths[i] : BACKGROUND_DEPTH;
  }

  Depth
  getDepth(int x, int y) const
  {
    if (x < 0 || x >= int (width) || y < 0 || y >= int (height))
      return BACKGROUND_DEPTH;

    return depths[x + width * y];
  }

  unsigned getWidth() const { return width; }
  unsigned getHeight() const { return height; }
};

struct DecisionTreeCPU
{
  tbb::task_scheduler_init tbb_init;

  struct Offsets
  {
    boost::int16_t du1, dv1, du2, dv2;
  };

  struct Node
  {
    Offsets offsets;
    boost::int16_t threshold;
  };

  boost::uint16_t depth;
  std::vector<Node> nodes;
  std::vector<Label> leaves;

  DecisionTreeCPU(const char * data)
  {
    std::memcpy (&depth, data, sizeof depth);
    data += sizeof depth;

    nodes.resize ((1 << depth) - 1);
    std::memcpy (&nodes.front (), data, nodes.size () * sizeof (Node));
    data += nodes.size () * sizeof (Node);

    leaves.resize (1 << depth);
    std::memcpy (&leaves.front (), data, leaves.size () * sizeof (Label));
    data += leaves.size () * sizeof (Label);
  }

  Label
  walk(const DepthImage & image, int x, int y) const
  {
    unsigned nid = 0;
    Depth d0 = image.getDepth(x, y);
    float scale = 1000.0f / d0;

    for(int node_depth = 0; node_depth < depth; ++node_depth)
    {
      const Node & node = nodes[nid];

      Depth d1 = image.getDepth (x + node.offsets.du1 * scale, y + node.offsets.dv1 * scale);
      Depth d2 = image.getDepth (x + node.offsets.du2 * scale, y + node.offsets.dv2 * scale);

      int feature = int (d1) - int (d2);

      if (feature > node.threshold)
        nid = nid * 2 + 2;
      else
        nid = nid * 2 + 1;
    }

    return leaves[nid - nodes.size()];
  }

  struct WalkHelper
  {
  private:
    const DecisionTreeCPU & tree;
    const DepthImage & image;
    std::vector<Label> & labels;

  public:
    WalkHelper(const DecisionTreeCPU & tree, const DepthImage & image, std::vector<Label> & labels)
      : tree(tree), image(image), labels(labels)
    {
    }

    void
    operator () (const tbb::blocked_range2d<unsigned> & range) const
    {
      for (unsigned y = range.rows().begin(); y < range.rows().end(); ++y)
        for (unsigned x = range.cols().begin(); x < range.cols().end(); ++x)
          labels[x + y * image.getWidth()] = image.getDepth(x, y) == BACKGROUND_DEPTH ?
                Labels::Background : tree.walk(image, x, y);
    }
  };

  void
  eval(const DepthImage & image, std::vector<Label> & labels) const
  {
    tbb::parallel_for(
          tbb::blocked_range2d<unsigned>(0, image.getHeight(), 0, image.getWidth()),
          WalkHelper(*this, image, labels)
    );
  }
};

int maxElementNoTie(int num, unsigned * elements)
{
  int max_element = 0;
  unsigned max = elements[max_element];

  for (int i = 1; i < num; ++i)
  {
    unsigned val = elements[i];
    if (max < val) { max_element = i; max = val; }
    else if (max == val) { max_element = -1; }
  }

  return max_element;
}

void filterLabels(unsigned width, unsigned height, const std::vector<Label> & noisyLabels, std::vector<Label> & labels, int radius)
{
  for (unsigned j = 0; j < width; ++j)
    for (unsigned i = 0; i < height; ++i)
    {
      unsigned idx = i * width + j;

      if (i < radius || i >= height - radius || j < radius || j >= width - radius || noisyLabels[idx] == Labels::Background)
      {
        labels[idx] = Labels::Background;
        continue;
      }

      int bins[Labels::NUM_LABELS] = { 0 };
      Label mode = -1;
      Label mode_count = 0;

      for (int dx = -radius; dx <= radius; ++dx)
        for (int dy = -radius; dy <= radius; ++dy)
        {
          Label current = noisyLabels[idx + dx + dy * width];
          ++bins[current];
          if (bins[current] > mode_count) {
            mode_count = bins[current];
            mode = current;
          }
        }

      labels[idx] = mode;
    }
}

struct ConsensusHelper
{
private:
  const std::vector<std::vector<Label> > & multi_labels;
  std::vector<Label> & labels;
  const DepthImage & depth_image;

public:
  ConsensusHelper(
      const std::vector<std::vector<Label> > & multi_labels,
      std::vector<Label> & labels,
      const DepthImage & depth_image
  )
    : multi_labels(multi_labels), labels(labels), depth_image(depth_image)
  {
  }

  void operator ()(const tbb::blocked_range2d<unsigned> & range) const
  {
    for (unsigned y = range.rows().begin(); y < range.rows().end(); ++y)
      for (unsigned x = range.cols().begin(); x < range.cols().end(); ++x)
      {
        std::size_t i = x + y * depth_image.getWidth();

        bool background = true;
        for (std::size_t ti = 0; ti < multi_labels.size (); ++ti)
          if (multi_labels[ti][i] != Labels::Background) background = false;

        if (background)
        {
          labels[i] = Labels::Background;
          continue;
        }

        unsigned bins[Labels::NUM_LABELS] = { 0 };

        for (std::size_t ti = 0; ti < multi_labels.size (); ++ti)
          ++bins[multi_labels[ti][i]];

        int consensus = maxElementNoTie(Labels::NUM_LABELS, bins);

        if (consensus == -1)
        {
          std::fill (bins, bins + Labels::NUM_LABELS, 0);
          Depth d = depth_image.getDepth (x, y);

          for (int off_x = -1; off_x <= 1; ++off_x)
            for (int off_y = -1; off_y <= 1; ++off_y)
            {
              Depth off_d = depth_image.getDepth (x + off_x, y + off_y);

              if (std::abs (d - off_d) < 50)
                for (std::size_t ti = 0; ti < multi_labels.size (); ++ti)
                  ++bins[multi_labels[ti][i]];
            }

          labels[i] = std::max_element (bins, bins + Labels::NUM_LABELS) - bins;
        }
        else
        {
          labels[i] = consensus;
        }
      }
  }
};

BodyPartsRecognizer::BodyPartsRecognizer(std::size_t num_trees, const char * trees[])
{
  this->trees.resize(num_trees);

  for (std::size_t i = 0; i < num_trees; ++i)
    this->trees[i].reset(new Tree(trees[i]));

#if GPU_CONSENSUS
  this->consensus_finder.reset(new ConsensusFinderGPU(num_trees));
#endif
}

void
BodyPartsRecognizer::recognize(const RGBDImage & image, std::vector<Label> & labels)
{
  labels.clear ();
  labels.resize (image.width * image.height);

  DepthImage depth_image (image);

  Stopwatch watch_threshold;

  depth_image.applyThreshold (500);

  __android_log_print(ANDROID_LOG_INFO, "BPR", "Thresholding: %d ms", watch_threshold.elapsedMs());

  std::vector<std::vector<Label> > multi_labels (trees.size ());

  for (std::size_t ti = 0; ti < trees.size (); ++ti)
  {
    Stopwatch watch_evaluation;

    multi_labels[ti].resize (labels.size ());
    trees[ti]->eval (depth_image, multi_labels[ti]);

    __android_log_print(ANDROID_LOG_INFO, "BPR", "Evaluating tree %d: %d ms", ti, watch_evaluation.elapsedMs());
  }

  Stopwatch watch_consensus;

  std::vector<Label> noisy_labels (labels.size ());

  tbb::parallel_for(
        tbb::blocked_range2d<unsigned>(0, depth_image.getHeight(), 0, depth_image.getWidth()),
        ConsensusHelper(multi_labels, noisy_labels, depth_image)
  );

  __android_log_print(ANDROID_LOG_INFO, "BPR", "Finding consensus: %d ms", watch_consensus.elapsedMs());

  Stopwatch watch_filtering;

  filterLabels(depth_image.getWidth(), depth_image.getHeight(), noisy_labels, labels, 2);

  __android_log_print(ANDROID_LOG_INFO, "BPR", "Filtering labels: %d ms", watch_consensus.elapsedMs());

}
<|endoftext|>


<commit_before>/*
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * Written (W) 2009 Soeren Sonnenburg
 * Copyright (C) 2009 Fraunhofer Institute FIRST and Max-Planck-Society
 */

#include "features/ImplicitWeightedSpecFeatures.h"
#include "lib/io.h"

CImplicitWeightedSpecFeatures::CImplicitWeightedSpecFeatures(CStringFeatures<uint16_t>* str, bool normalize) : CDotFeatures()
{
	ASSERT(str);
	SG_REF(strings)
	strings=str;
	normalization_factors=NULL;
	spec_weights=NULL;
	num_strings = str->get_num_vectors();
	alphabet_size = str->get_original_num_symbols();
	degree=str->get_order();
	set_wd_weights();

	SG_DEBUG("WEIGHTED SPEC alphasz=%d, size=%d, num_str=%d\n", alphabet_size,
			spec_size, num_strings);

	if (normalize)
		compute_normalization_const();
}

void CImplicitWeightedSpecFeatures::compute_normalization_const()
{
	float64_t* factors=new float64_t[num_strings];

	for (int32_t i=0; i<num_strings; i++)
		factors[i]=1.0/CMath::sqrt(dot(i,i));

	normalization_factors=factors;
	//CMath::display_vector(normalization_factors, num_strings, "n");
}

bool CImplicitWeightedSpecFeatures::set_wd_weights()
{
	delete[] spec_weights;
	spec_weights=new float64_t[degree];

	int32_t i;
	float64_t sum=0;
	spec_size=0;

	for (i=0; i<degree; i++)
	{
		spec_size+=CMath::pow(alphabet_size, i+1);
		spec_weights[i]=degree-i;
		sum+=spec_weights[i];
	}
	for (i=0; i<degree; i++)
		spec_weights[i]=CMath::sqrt(spec_weights[i]/sum);

	return spec_weights!=NULL;
}

bool CImplicitWeightedSpecFeatures::set_weights(float64_t* w, int32_t d)
{
	ASSERT(d==degree);

	delete[] spec_weights;
	spec_weights=new float64_t[degree];
	for (int32_t i=0; i<degree; i++)
		spec_weights[i]=CMath::sqrt(w[i]);
	return true;
}

CImplicitWeightedSpecFeatures::CImplicitWeightedSpecFeatures(const CImplicitWeightedSpecFeatures& orig) : CDotFeatures(orig),
	num_strings(orig.num_strings),
	alphabet_size(orig.alphabet_size), spec_size(orig.spec_size)
{
	SG_NOTIMPLEMENTED;
	SG_REF(strings);
}

CImplicitWeightedSpecFeatures::~CImplicitWeightedSpecFeatures()
{
	SG_UNREF(strings);
	delete[] spec_weights;
	delete[] normalization_factors;
}

float64_t CImplicitWeightedSpecFeatures::dot(int32_t vec_idx1, int32_t vec_idx2)
{
	ASSERT(vec_idx1 < num_strings);
	ASSERT(vec_idx2 < num_strings);

	int32_t len1=-1;
	int32_t len2=-1;
	uint16_t* vec1=strings->get_feature_vector(vec_idx1, len1);
	uint16_t* vec2=strings->get_feature_vector(vec_idx2, len2);

	float64_t result=0;
	uint8_t mask=0;

	for (int32_t d=0; d<degree; d++)
	{
		mask = mask | (1 << (degree-d-1));
		uint16_t masked=strings->get_masked_symbols(0xffff, mask);

		int32_t left_idx=0;
		int32_t right_idx=0;
		float64_t weight=spec_weights[d]*spec_weights[d];

		while (left_idx < len1 && right_idx < len2)
		{
			uint16_t lsym=vec1[left_idx] & masked;
			uint16_t rsym=vec2[right_idx] & masked;

			if (lsym == rsym)
			{
				int32_t old_left_idx=left_idx;
				int32_t old_right_idx=right_idx;

				while (left_idx<len1 && (vec1[left_idx] & masked) ==lsym)
					left_idx++;

				while (right_idx<len2 && (vec2[right_idx] & masked) ==lsym)
					right_idx++;

				result+=weight*(left_idx-old_left_idx)*(right_idx-old_right_idx);
			}
			else if (lsym<rsym)
				left_idx++;
			else
				right_idx++;
		}
	}

	if (normalization_factors)
		return result*normalization_factors[vec_idx1]*normalization_factors[vec_idx2];
	else
		return result;
}

float64_t CImplicitWeightedSpecFeatures::dense_dot(int32_t vec_idx1, const float64_t* vec2, int32_t vec2_len)
{
	ASSERT(vec2_len == spec_size);
	ASSERT(vec_idx1 < num_strings);

	float64_t result=0;
	int32_t len1=-1;
	uint16_t* vec1=strings->get_feature_vector(vec_idx1, len1);

	if (vec1 && len1>0)
	{
		for (int32_t j=0; j<len1; j++)
		{
			uint8_t mask=0;
			int32_t offs=0;
			uint16_t v=*vec1++;

			for (int32_t d=0; d<degree; d++)
			{
				mask = mask | (1 << (degree-d-1));
				int32_t idx=strings->get_masked_symbols(v, mask);
				idx=strings->shift_symbol(idx, degree-d-1);
				result += vec2[offs + idx]*spec_weights[d];
				offs+=strings->shift_offset(1,d+1);
			}
		}

		if (normalization_factors)
			result*=normalization_factors[vec_idx1];
	}
	else
		SG_ERROR("huh?\n");

	return result;
}

void CImplicitWeightedSpecFeatures::add_to_dense_vec(float64_t alpha, int32_t vec_idx1, float64_t* vec2, int32_t vec2_len, bool abs_val)
{
	int32_t len1=-1;
	uint16_t* vec=strings->get_feature_vector(vec_idx1, len1);

	if (normalization_factors)
		alpha*=normalization_factors[vec_idx1];

	if (vec && len1>0)
	{
		for (int32_t j=0; j<len1; j++)
		{
			uint8_t mask=0;
			int32_t offs=0;
			for (int32_t d=0; d<degree; d++)
			{
				mask = mask | (1 << (degree-d-1));
				int32_t idx=strings->get_masked_symbols(vec[j], mask);
				idx=strings->shift_symbol(idx, degree-d-1);
				if (abs_val)
					vec2[offs + idx] += CMath::abs(alpha*spec_weights[d]);
				else
					vec2[offs + idx] += alpha*spec_weights[d];
				offs+=strings->shift_offset(1,d+1);
			}
		}
	}
}

CFeatures* CImplicitWeightedSpecFeatures::duplicate() const
{
	return new CImplicitWeightedSpecFeatures(*this);
}
<commit_msg>fix same bug also in implicit wd spec features<commit_after>/*
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * Written (W) 2009 Soeren Sonnenburg
 * Copyright (C) 2009 Fraunhofer Institute FIRST and Max-Planck-Society
 */

#include "features/ImplicitWeightedSpecFeatures.h"
#include "lib/io.h"

CImplicitWeightedSpecFeatures::CImplicitWeightedSpecFeatures(CStringFeatures<uint16_t>* str, bool normalize) : CDotFeatures()
{
	ASSERT(str);
	strings=str;
	SG_REF(strings)
	normalization_factors=NULL;
	spec_weights=NULL;
	num_strings = str->get_num_vectors();
	alphabet_size = str->get_original_num_symbols();
	degree=str->get_order();
	set_wd_weights();

	SG_DEBUG("WEIGHTED SPEC alphasz=%d, size=%d, num_str=%d\n", alphabet_size,
			spec_size, num_strings);

	if (normalize)
		compute_normalization_const();
}

void CImplicitWeightedSpecFeatures::compute_normalization_const()
{
	float64_t* factors=new float64_t[num_strings];

	for (int32_t i=0; i<num_strings; i++)
		factors[i]=1.0/CMath::sqrt(dot(i,i));

	normalization_factors=factors;
	//CMath::display_vector(normalization_factors, num_strings, "n");
}

bool CImplicitWeightedSpecFeatures::set_wd_weights()
{
	delete[] spec_weights;
	spec_weights=new float64_t[degree];

	int32_t i;
	float64_t sum=0;
	spec_size=0;

	for (i=0; i<degree; i++)
	{
		spec_size+=CMath::pow(alphabet_size, i+1);
		spec_weights[i]=degree-i;
		sum+=spec_weights[i];
	}
	for (i=0; i<degree; i++)
		spec_weights[i]=CMath::sqrt(spec_weights[i]/sum);

	return spec_weights!=NULL;
}

bool CImplicitWeightedSpecFeatures::set_weights(float64_t* w, int32_t d)
{
	ASSERT(d==degree);

	delete[] spec_weights;
	spec_weights=new float64_t[degree];
	for (int32_t i=0; i<degree; i++)
		spec_weights[i]=CMath::sqrt(w[i]);
	return true;
}

CImplicitWeightedSpecFeatures::CImplicitWeightedSpecFeatures(const CImplicitWeightedSpecFeatures& orig) : CDotFeatures(orig),
	num_strings(orig.num_strings),
	alphabet_size(orig.alphabet_size), spec_size(orig.spec_size)
{
	SG_NOTIMPLEMENTED;
	SG_REF(strings);
}

CImplicitWeightedSpecFeatures::~CImplicitWeightedSpecFeatures()
{
	SG_UNREF(strings);
	delete[] spec_weights;
	delete[] normalization_factors;
}

float64_t CImplicitWeightedSpecFeatures::dot(int32_t vec_idx1, int32_t vec_idx2)
{
	ASSERT(vec_idx1 < num_strings);
	ASSERT(vec_idx2 < num_strings);

	int32_t len1=-1;
	int32_t len2=-1;
	uint16_t* vec1=strings->get_feature_vector(vec_idx1, len1);
	uint16_t* vec2=strings->get_feature_vector(vec_idx2, len2);

	float64_t result=0;
	uint8_t mask=0;

	for (int32_t d=0; d<degree; d++)
	{
		mask = mask | (1 << (degree-d-1));
		uint16_t masked=strings->get_masked_symbols(0xffff, mask);

		int32_t left_idx=0;
		int32_t right_idx=0;
		float64_t weight=spec_weights[d]*spec_weights[d];

		while (left_idx < len1 && right_idx < len2)
		{
			uint16_t lsym=vec1[left_idx] & masked;
			uint16_t rsym=vec2[right_idx] & masked;

			if (lsym == rsym)
			{
				int32_t old_left_idx=left_idx;
				int32_t old_right_idx=right_idx;

				while (left_idx<len1 && (vec1[left_idx] & masked) ==lsym)
					left_idx++;

				while (right_idx<len2 && (vec2[right_idx] & masked) ==lsym)
					right_idx++;

				result+=weight*(left_idx-old_left_idx)*(right_idx-old_right_idx);
			}
			else if (lsym<rsym)
				left_idx++;
			else
				right_idx++;
		}
	}

	if (normalization_factors)
		return result*normalization_factors[vec_idx1]*normalization_factors[vec_idx2];
	else
		return result;
}

float64_t CImplicitWeightedSpecFeatures::dense_dot(int32_t vec_idx1, const float64_t* vec2, int32_t vec2_len)
{
	ASSERT(vec2_len == spec_size);
	ASSERT(vec_idx1 < num_strings);

	float64_t result=0;
	int32_t len1=-1;
	uint16_t* vec1=strings->get_feature_vector(vec_idx1, len1);

	if (vec1 && len1>0)
	{
		for (int32_t j=0; j<len1; j++)
		{
			uint8_t mask=0;
			int32_t offs=0;
			uint16_t v=*vec1++;

			for (int32_t d=0; d<degree; d++)
			{
				mask = mask | (1 << (degree-d-1));
				int32_t idx=strings->get_masked_symbols(v, mask);
				idx=strings->shift_symbol(idx, degree-d-1);
				result += vec2[offs + idx]*spec_weights[d];
				offs+=strings->shift_offset(1,d+1);
			}
		}

		if (normalization_factors)
			result*=normalization_factors[vec_idx1];
	}
	else
		SG_ERROR("huh?\n");

	return result;
}

void CImplicitWeightedSpecFeatures::add_to_dense_vec(float64_t alpha, int32_t vec_idx1, float64_t* vec2, int32_t vec2_len, bool abs_val)
{
	int32_t len1=-1;
	uint16_t* vec=strings->get_feature_vector(vec_idx1, len1);

	if (normalization_factors)
		alpha*=normalization_factors[vec_idx1];

	if (vec && len1>0)
	{
		for (int32_t j=0; j<len1; j++)
		{
			uint8_t mask=0;
			int32_t offs=0;
			for (int32_t d=0; d<degree; d++)
			{
				mask = mask | (1 << (degree-d-1));
				int32_t idx=strings->get_masked_symbols(vec[j], mask);
				idx=strings->shift_symbol(idx, degree-d-1);
				if (abs_val)
					vec2[offs + idx] += CMath::abs(alpha*spec_weights[d]);
				else
					vec2[offs + idx] += alpha*spec_weights[d];
				offs+=strings->shift_offset(1,d+1);
			}
		}
	}
}

CFeatures* CImplicitWeightedSpecFeatures::duplicate() const
{
	return new CImplicitWeightedSpecFeatures(*this);
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "src/trace_processor/importers/json/json_trace_parser.h"

#include <inttypes.h>

#include <limits>
#include <string>

#include "perfetto/base/logging.h"
#include "perfetto/ext/base/string_view.h"
#include "perfetto/ext/base/utils.h"
#include "src/trace_processor/importers/json/json_tracker.h"
#include "src/trace_processor/importers/json/json_utils.h"
#include "src/trace_processor/process_tracker.h"
#include "src/trace_processor/slice_tracker.h"
#include "src/trace_processor/trace_processor_context.h"
#include "src/trace_processor/track_tracker.h"

namespace perfetto {
namespace trace_processor {

JsonTraceParser::JsonTraceParser(TraceProcessorContext* context)
    : context_(context), systrace_line_parser_(context) {}

JsonTraceParser::~JsonTraceParser() = default;

void JsonTraceParser::ParseFtracePacket(uint32_t,
                                        int64_t,
                                        TimestampedTracePiece) {
  PERFETTO_FATAL("Json Trace Parser cannot handle ftrace packets.");
}

void JsonTraceParser::ParseTracePacket(int64_t timestamp,
                                       TimestampedTracePiece ttp) {
  PERFETTO_DCHECK(json::IsJsonSupported());

#if PERFETTO_BUILDFLAG(PERFETTO_TP_JSON)
  PERFETTO_DCHECK(ttp.type == TimestampedTracePiece::Type::kJsonValue ||
                  ttp.type == TimestampedTracePiece::Type::kSystraceLine);
  if (ttp.type == TimestampedTracePiece::Type::kSystraceLine) {
    systrace_line_parser_.ParseLine(*ttp.systrace_line);
    return;
  }

  const Json::Value& value = *(ttp.json_value);

  ProcessTracker* procs = context_->process_tracker.get();
  TraceStorage* storage = context_->storage.get();
  SliceTracker* slice_tracker = context_->slice_tracker.get();

  auto& ph = value["ph"];
  if (!ph.isString())
    return;
  char phase = *ph.asCString();

  base::Optional<uint32_t> opt_pid;
  base::Optional<uint32_t> opt_tid;

  if (value.isMember("pid"))
    opt_pid = json::CoerceToUint32(value["pid"]);
  if (value.isMember("tid"))
    opt_tid = json::CoerceToUint32(value["tid"]);

  uint32_t pid = opt_pid.value_or(0);
  uint32_t tid = opt_tid.value_or(pid);

  base::StringView cat = value.isMember("cat")
                             ? base::StringView(value["cat"].asCString())
                             : base::StringView();
  base::StringView name = value.isMember("name")
                              ? base::StringView(value["name"].asCString())
                              : base::StringView();

  StringId cat_id = storage->InternString(cat);
  StringId name_id = storage->InternString(name);
  UniqueTid utid = procs->UpdateThread(tid, pid);

  switch (phase) {
    case 'B': {  // TRACE_EVENT_BEGIN.
      TrackId track_id = context_->track_tracker->InternThreadTrack(utid);
      slice_tracker->Begin(timestamp, track_id, cat_id, name_id);
      break;
    }
    case 'E': {  // TRACE_EVENT_END.
      TrackId track_id = context_->track_tracker->InternThreadTrack(utid);
      slice_tracker->End(timestamp, track_id, cat_id, name_id);
      break;
    }
    case 'X': {  // TRACE_EVENT (scoped event).
      base::Optional<int64_t> opt_dur =
          JsonTracker::GetOrCreate(context_)->CoerceToTs(value["dur"]);
      if (!opt_dur.has_value())
        return;
      TrackId track_id = context_->track_tracker->InternThreadTrack(utid);
      slice_tracker->Scoped(timestamp, track_id, cat_id, name_id,
                            opt_dur.value());
      break;
    }
    case 'M': {  // Metadata events (process and thread names).
      if (strcmp(value["name"].asCString(), "thread_name") == 0 &&
          !value["args"]["name"].empty()) {
        const char* thread_name = value["args"]["name"].asCString();
        auto thread_name_id = context_->storage->InternString(thread_name);
        procs->UpdateThreadName(tid, thread_name_id);
        break;
      }
      if (strcmp(value["name"].asCString(), "process_name") == 0 &&
          !value["args"]["name"].empty()) {
        const char* proc_name = value["args"]["name"].asCString();
        procs->SetProcessMetadata(pid, base::nullopt, proc_name);
        break;
      }
    }
  }
#else
  perfetto::base::ignore_result(timestamp);
  perfetto::base::ignore_result(ttp);
  perfetto::base::ignore_result(context_);
  PERFETTO_ELOG("Cannot parse JSON trace due to missing JSON support");
#endif  // PERFETTO_BUILDFLAG(PERFETTO_TP_JSON)
}

}  // namespace trace_processor
}  // namespace perfetto

<commit_msg>tp: ingest args from json events<commit_after>/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "src/trace_processor/importers/json/json_trace_parser.h"

#include <inttypes.h>

#include <limits>
#include <string>

#include "perfetto/base/logging.h"
#include "perfetto/ext/base/string_view.h"
#include "perfetto/ext/base/utils.h"
#include "src/trace_processor/importers/json/json_tracker.h"
#include "src/trace_processor/importers/json/json_utils.h"
#include "src/trace_processor/process_tracker.h"
#include "src/trace_processor/slice_tracker.h"
#include "src/trace_processor/trace_processor_context.h"
#include "src/trace_processor/track_tracker.h"

namespace perfetto {
namespace trace_processor {

JsonTraceParser::JsonTraceParser(TraceProcessorContext* context)
    : context_(context), systrace_line_parser_(context) {}

JsonTraceParser::~JsonTraceParser() = default;

void JsonTraceParser::ParseFtracePacket(uint32_t,
                                        int64_t,
                                        TimestampedTracePiece) {
  PERFETTO_FATAL("Json Trace Parser cannot handle ftrace packets.");
}

void JsonTraceParser::ParseTracePacket(int64_t timestamp,
                                       TimestampedTracePiece ttp) {
  PERFETTO_DCHECK(json::IsJsonSupported());

#if PERFETTO_BUILDFLAG(PERFETTO_TP_JSON)
  PERFETTO_DCHECK(ttp.type == TimestampedTracePiece::Type::kJsonValue ||
                  ttp.type == TimestampedTracePiece::Type::kSystraceLine);
  if (ttp.type == TimestampedTracePiece::Type::kSystraceLine) {
    systrace_line_parser_.ParseLine(*ttp.systrace_line);
    return;
  }

  const Json::Value& value = *(ttp.json_value);

  ProcessTracker* procs = context_->process_tracker.get();
  TraceStorage* storage = context_->storage.get();
  SliceTracker* slice_tracker = context_->slice_tracker.get();

  auto& ph = value["ph"];
  if (!ph.isString())
    return;
  char phase = *ph.asCString();

  base::Optional<uint32_t> opt_pid;
  base::Optional<uint32_t> opt_tid;

  if (value.isMember("pid"))
    opt_pid = json::CoerceToUint32(value["pid"]);
  if (value.isMember("tid"))
    opt_tid = json::CoerceToUint32(value["tid"]);

  uint32_t pid = opt_pid.value_or(0);
  uint32_t tid = opt_tid.value_or(pid);

  base::StringView cat = value.isMember("cat")
                             ? base::StringView(value["cat"].asCString())
                             : base::StringView();
  base::StringView name = value.isMember("name")
                              ? base::StringView(value["name"].asCString())
                              : base::StringView();

  StringId cat_id = storage->InternString(cat);
  StringId name_id = storage->InternString(name);
  UniqueTid utid = procs->UpdateThread(tid, pid);

  auto args_inserter = [this, &value](ArgsTracker::BoundInserter* inserter) {
    if (value.isMember("args")) {
      json::AddJsonValueToArgs(value["args"], /* flat_key = */ "args",
                               /* key = */ "args", context_->storage.get(),
                               inserter);
    }
  };
  switch (phase) {
    case 'B': {  // TRACE_EVENT_BEGIN.
      TrackId track_id = context_->track_tracker->InternThreadTrack(utid);
      slice_tracker->Begin(timestamp, track_id, cat_id, name_id, args_inserter);
      break;
    }
    case 'E': {  // TRACE_EVENT_END.
      TrackId track_id = context_->track_tracker->InternThreadTrack(utid);
      slice_tracker->End(timestamp, track_id, cat_id, name_id, args_inserter);
      break;
    }
    case 'X': {  // TRACE_EVENT (scoped event).
      base::Optional<int64_t> opt_dur =
          JsonTracker::GetOrCreate(context_)->CoerceToTs(value["dur"]);
      if (!opt_dur.has_value())
        return;
      TrackId track_id = context_->track_tracker->InternThreadTrack(utid);
      slice_tracker->Scoped(timestamp, track_id, cat_id, name_id,
                            opt_dur.value(), args_inserter);
      break;
    }
    case 'M': {  // Metadata events (process and thread names).
      if (strcmp(value["name"].asCString(), "thread_name") == 0 &&
          !value["args"]["name"].empty()) {
        const char* thread_name = value["args"]["name"].asCString();
        auto thread_name_id = context_->storage->InternString(thread_name);
        procs->UpdateThreadName(tid, thread_name_id);
        break;
      }
      if (strcmp(value["name"].asCString(), "process_name") == 0 &&
          !value["args"]["name"].empty()) {
        const char* proc_name = value["args"]["name"].asCString();
        procs->SetProcessMetadata(pid, base::nullopt, proc_name);
        break;
      }
    }
  }
#else
  perfetto::base::ignore_result(timestamp);
  perfetto::base::ignore_result(ttp);
  perfetto::base::ignore_result(context_);
  PERFETTO_ELOG("Cannot parse JSON trace due to missing JSON support");
#endif  // PERFETTO_BUILDFLAG(PERFETTO_TP_JSON)
}

}  // namespace trace_processor
}  // namespace perfetto

<|endoftext|>