<commit_before>#include <iostream>
#include <fstream>
#include <math.h>
#include <sys/time.h>
#include <vector>
#include <algorithm>
#include <map>
#include <numeric>
#include <functional>
#include <string.h>
#include <sstream>
#include <pthread.h>
#include <thread>
#include "zlib.h"
#include <sys/stat.h>

using namespace std;
//compile with openMP g++ linearBCV.cpp -O3 -std=c++11 -mavx2 -msse4.2 -pthread -fopenmp -lz -o linear11

//some global variables
int RAND_SAMPLES; //will all be set later (if needed)
int image_m; int image_n; int image_o; int image_d=1;
float SSD0=0.0; float SSD1=0.0; float SSD2=0.0; float distfx_global; float beta=1;
//float SIGMA=8.0;
int qc=1;

//struct for multi-threading of mind-calculation
struct mind_data{
	float* im1;
    float* d1;
    uint64_t* mindq;
    int qs;
    int ind_d1;
};

float quantile(float* values,int length,float quant1){
    float* values2=new float[length];
    for(int i=0;i<length;i++){
        values2[i]=values[i];
    }
    int quantind=length*min(max(quant1,0.01f),0.99f);
    //printf("quantind: %d/%d\n",quantind,length);
    nth_element(values2,values2+quantind,values2+length);
    float med1=values2[quantind];
    // delete values2;
    return med1;
}
bool RIGID=false;

struct parameters{
    float alpha; int levels; bool segment,affine,rigid;
    vector<int> grid_spacing; vector<int> search_radius;
    vector<int> quantisation;
    string fixed_file,moving_file,output_stem,moving_seg_file,affine_file,deformed_file;
};

#include "imageIOgzType.h"
#include "transformations.h"
#include "QRsolve.h"
#include "affineLTS1.h"
#include "MINDSSCbox.h"
#include "dataCostD.h"
#include "parseArguments.h"

int main (int argc, char * const argv[]) {

    //PARSE INPUT ARGUMENTS

    if(argc<4||argv[1][1]=='h'){
        cout<<"=============================================================\n";
        cout<<"Usage (required input arguments):\n";
        cout<<"./linearBCV -F fixed.nii.gz -M moving.nii.gz -O output\n";
        cout<<"optional parameters:\n";
        cout<<" -R <find rigid instead of affine transform> (default 0)\n";
        cout<<" -l <number of levels> (default 4)\n";
        cout<<" -G <grid spacing for each level> (default 7x6x5x4)\n";
        cout<<" -L <maximum search radius - each level> (default 5x4x3x2)\n";
        cout<<" -Q <quantisation of search step size> (default 4x3x2x1)\n";
        cout<<"=============================================================\n";
        return 1;
    }
    parameters args;
    //defaults
    args.grid_spacing={7,6,5,4};
    args.search_radius={5,4,3,2};
    args.quantisation={4,3,2,1};
    args.levels=4;
    parseCommandLine(args, argc, argv);

    size_t split_fixed=args.fixed_file.find_last_of("/\\");
    if(split_fixed==string::npos){
        split_fixed=-1;
    }
    size_t split_moving=args.moving_file.find_last_of("/\\");
    if(split_moving==string::npos){
        split_moving=-1;
    }

    if(args.fixed_file.substr(args.fixed_file.length()-2)!="gz"){
        cout<<"images must have nii.gz format\n";
        return -1;
    }
    if(args.moving_file.substr(args.moving_file.length()-2)!="gz"){
        cout<<"images must have nii.gz format\n";
        return -1;
    }

    cout<<"Starting linear reg. of "<<args.fixed_file.substr(split_fixed+1)<<" and "<<args.moving_file.substr(split_moving+1)<<"\n";
    cout<<"=============================================================\n";

    if(args.rigid){
        cout<<"Searching only for rigid (6 parameter) transform\n";
        RIGID=true;
    }

	qc=2;

	float alpha=1;
    //READ IMAGES and INITIALISE ARRAYS

    timeval time1,time2,time1a,time2a;

    RAND_SAMPLES=1; //fixed/efficient random sampling strategy

    float* im1; float* im1b;

    int M,N,O,P; //image dimensions

    //==ALWAYS ALLOCATE MEMORY FOR HEADER ===/
    char* header=new char[352];

    readNifti(args.fixed_file,im1b,header,M,N,O,P);
    image_m=M; image_n=N; image_o=O;

    readNifti(args.moving_file,im1,header,M,N,O,P);

    if(M!=image_m|N!=image_n|O!=image_o){
        cout<<"Inconsistent image sizes (must have same dimensions)\n";
        return -1;
    }

    int m=image_m; int n=image_n; int o=image_o; int sz=m*n*o;

    //assume we are working with CT scans (add 1024 HU)
    float thresholdF=-1024; float thresholdM=-1024;

    for(int i=0;i<sz;i++){
        im1b[i]-=thresholdF;
        im1[i]-=thresholdM;
    }

	float *warped1=new float[m*n*o];
    float *warped2=new float[m*n*o];

	int step1; int hw1; float quant1;

    vector<int> mind_step;
    for(int i=0;i<args.quantisation.size();i++){
        mind_step.push_back(floor(0.5f*(float)args.quantisation[i]+1.0f));
    }
    float* X=new float[4*4];

    float Xprev[16]={1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1};
    for(int i=0;i<16;i++){
        X[i]=Xprev[i];
    }

    uint64_t* im1_mind=new uint64_t[m*n*o];
    uint64_t* im1b_mind=new uint64_t[m*n*o];
    uint64_t* warped_mind=new uint64_t[m*n*o];

	gettimeofday(&time1a, NULL);
    float timeDataSmooth=0;
	//==========================================================================================
	//==========================================================================================
	float* bench=new float[6*args.levels];
	for(int level=0;level<args.levels;level++){
        quant1=args.quantisation[level];
        step1=args.grid_spacing[level];
        hw1=args.search_radius[level];

        float Xinv[16]; float Ident[16]={1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1};
        qrsolve(Xinv,Xprev,Ident,4,4);

        warpAffine(warped2,im1b,Xinv,m,n,o);
        warpAffine(warped1,im1,Xprev,m,n,o);

        float prev=mind_step[max(level-1,0)];
        float curr=mind_step[level];

        float timeMIND=0; float timeSmooth=0; float timeData=0; float timeTrans=0;

        if(level==0|prev!=curr){
            gettimeofday(&time1, NULL);
            descriptor(im1_mind,im1,m,n,o,mind_step[level]);//max(min(quant1,2.0f),1.0f)
            descriptor(im1b_mind,im1b,m,n,o,mind_step[level]);
            gettimeofday(&time2, NULL);
            timeMIND+=time2.tv_sec+time2.tv_usec/1e6-(time1.tv_sec+time1.tv_usec/1e6);
		}

		int len3=pow(hw1*2+1,3);
		int m1=m/step1; int n1=n/step1; int o1=o/step1; int sz1=m1*n1*o1;

        float* costall=new float[sz1*len3]; float* costall2=new float[sz1*len3];

        //cout<<"==========================================================\n";
		//cout<<"Level "<<level<<" grid="<<step1<<" hw="<<hw1<<" quant="<<quant1<<"\n";
		//cout<<"==========================================================\n";

        //FULL-REGISTRATION FORWARDS
        gettimeofday(&time1, NULL);
        gettimeofday(&time2, NULL);
		timeTrans+=time2.tv_sec+time2.tv_usec/1e6-(time1.tv_sec+time1.tv_usec/1e6);
        cout<<"T"<<flush;
        gettimeofday(&time1, NULL);
		descriptor(warped_mind,warped1,m,n,o,mind_step[level]);

        gettimeofday(&time2, NULL);
		timeMIND+=time2.tv_sec+time2.tv_usec/1e6-(time1.tv_sec+time1.tv_usec/1e6);
        cout<<"M"<<flush;
        gettimeofday(&time1, NULL);
        dataCostCL((unsigned long*)im1b_mind,(unsigned long*)warped_mind,costall,m,n,o,len3,step1,hw1,quant1,alpha,RAND_SAMPLES);
        gettimeofday(&time2, NULL);

		timeData+=time2.tv_sec+time2.tv_usec/1e6-(time1.tv_sec+time1.tv_usec/1e6);
        cout<<"D"<<flush;
        gettimeofday(&time1, NULL);
        gettimeofday(&time2, NULL);
		timeSmooth+=time2.tv_sec+time2.tv_usec/1e6-(time1.tv_sec+time1.tv_usec/1e6);
        cout<<"S"<<flush;

        //FULL-REGISTRATION BACKWARDS
        gettimeofday(&time1, NULL);
		gettimeofday(&time2, NULL);
		timeTrans+=time2.tv_sec+time2.tv_usec/1e6-(time1.tv_sec+time1.tv_usec/1e6);
        cout<<"T"<<flush;
        gettimeofday(&time1, NULL);
		descriptor(warped_mind,warped2,m,n,o,mind_step[level]);

        gettimeofday(&time2, NULL);
		timeMIND+=time2.tv_sec+time2.tv_usec/1e6-(time1.tv_sec+time1.tv_usec/1e6);
        cout<<"M"<<flush;
        gettimeofday(&time1, NULL);
        dataCostCL((unsigned long*)im1_mind,(unsigned long*)warped_mind,costall2,m,n,o,len3,step1,hw1,quant1,alpha,RAND_SAMPLES);
        gettimeofday(&time2, NULL);
		timeData+=time2.tv_sec+time2.tv_usec/1e6-(time1.tv_sec+time1.tv_usec/1e6);
        cout<<"DS\n"<<flush;
        gettimeofday(&time1, NULL);
        estimateAffine2(X,Xprev,im1b,im1,costall,costall2,step1,quant1,hw1);

        gettimeofday(&time2, NULL);
		timeSmooth+=time2.tv_sec+time2.tv_usec/1e6-(time1.tv_sec+time1.tv_usec/1e6);
        //cout<<"S"<<flush;

        printf("t: MIND=%2.2f, data=%2.2f, affine=%2.2f, speed=%2.2e dof/s\n",timeMIND,timeData,timeSmooth,2.0*(float)sz1*(float)len3/(timeData+timeSmooth));

        gettimeofday(&time1, NULL);

        gettimeofday(&time2, NULL);
        float timeMapping=time2.tv_sec+time2.tv_usec/1e6-(time1.tv_sec+time1.tv_usec/1e6);

        for(int i=0;i<16;i++){
            Xprev[i]=X[i];
        }

        timeDataSmooth+=(timeSmooth+timeData+timeMIND+timeTrans);

        delete costall; delete costall2;

	}
    delete im1_mind;
    delete im1b_mind;
	//==========================================================================================
	//==========================================================================================

    gettimeofday(&time2a, NULL);
	float timeALL=time2a.tv_sec+time2a.tv_usec/1e6-(time1a.tv_sec+time1a.tv_usec/1e6);

    string outputfile;
    outputfile.append(args.output_stem);
    outputfile.append("_matrix.txt");

    ofstream matfile;
    matfile.open(outputfile);

    for(int i=0;i<4;i++){
        matfile<<X[i]<<"  "<<X[i+4]<<"  "<<X[i+8]<<"  "<<X[i+12]<<"\n";

        printf("%+4.3f | %+4.3f | %+4.3f | %+4.3f \n",X[i],X[i+4],X[i+8],X[i+12]);
    }
    matfile.close();

    // if SEGMENTATION of moving image is provided APPLY SAME TRANSFORM
    if(args.segment){
        short* seg2;
        readNifti(args.moving_seg_file,seg2,header,M,N,O,P);

        float* zero=new float[sz];
        short* segw=new short[sz];
        fill(segw,segw+sz,0);

        warpAffineS(segw,seg2,X,zero,zero,zero);

        string outputseg;
        outputseg.append(args.output_stem);
        outputseg.append("_deformed_seg.nii.gz");

        gzWriteSegment(outputseg,segw,header,m,n,o,1);
    }

	cout<<"Finished. Total time: "<<timeALL<<" sec. ("<<timeDataSmooth<<" sec. for MIND+data+affine+trans)\n";

	return 0;
}
<commit_msg>fixed affine warp in linearBCV<commit_after>#include <iostream>
#include <fstream>
#include <math.h>
#include <sys/time.h>
#include <vector>
#include <algorithm>
#include <map>
#include <numeric>
#include <functional>
#include <string.h>
#include <sstream>
#include <pthread.h>
#include <thread>
#include "zlib.h"
#include <sys/stat.h>

using namespace std;
//compile with openMP g++ linearBCV.cpp -O3 -std=c++11 -mavx2 -msse4.2 -pthread -fopenmp -lz -o linear11

//some global variables
int RAND_SAMPLES; //will all be set later (if needed)
int image_m; int image_n; int image_o; int image_d=1;
float SSD0=0.0; float SSD1=0.0; float SSD2=0.0; float distfx_global; float beta=1;
//float SIGMA=8.0;
int qc=1;

//struct for multi-threading of mind-calculation
struct mind_data{
	float* im1;
    float* d1;
    uint64_t* mindq;
    int qs;
    int ind_d1;
};

float quantile(float* values,int length,float quant1){
    float* values2=new float[length];
    for(int i=0;i<length;i++){
        values2[i]=values[i];
    }
    int quantind=length*min(max(quant1,0.01f),0.99f);
    //printf("quantind: %d/%d\n",quantind,length);
    nth_element(values2,values2+quantind,values2+length);
    float med1=values2[quantind];
    // delete values2;
    return med1;
}
bool RIGID=false;

struct parameters{
    float alpha; int levels; bool segment,affine,rigid;
    vector<int> grid_spacing; vector<int> search_radius;
    vector<int> quantisation;
    string fixed_file,moving_file,output_stem,moving_seg_file,affine_file,deformed_file;
};

#include "imageIOgzType.h"
#include "transformations.h"
#include "QRsolve.h"
#include "affineLTS1.h"
#include "MINDSSCbox.h"
#include "dataCostD.h"
#include "parseArguments.h"

int main (int argc, char * const argv[]) {

    //PARSE INPUT ARGUMENTS

    if(argc<4||argv[1][1]=='h'){
        cout<<"=============================================================\n";
        cout<<"Usage (required input arguments):\n";
        cout<<"./linearBCV -F fixed.nii.gz -M moving.nii.gz -O output\n";
        cout<<"optional parameters:\n";
        cout<<" -R <find rigid instead of affine transform> (default 0)\n";
        cout<<" -l <number of levels> (default 4)\n";
        cout<<" -G <grid spacing for each level> (default 7x6x5x4)\n";
        cout<<" -L <maximum search radius - each level> (default 5x4x3x2)\n";
        cout<<" -Q <quantisation of search step size> (default 4x3x2x1)\n";
        cout<<"=============================================================\n";
        return 1;
    }
    parameters args;
    //defaults
    args.grid_spacing={7,6,5,4};
    args.search_radius={5,4,3,2};
    args.quantisation={4,3,2,1};
    args.levels=4;
    parseCommandLine(args, argc, argv);

    size_t split_fixed=args.fixed_file.find_last_of("/\\");
    if(split_fixed==string::npos){
        split_fixed=-1;
    }
    size_t split_moving=args.moving_file.find_last_of("/\\");
    if(split_moving==string::npos){
        split_moving=-1;
    }

    if(args.fixed_file.substr(args.fixed_file.length()-2)!="gz"){
        cout<<"images must have nii.gz format\n";
        return -1;
    }
    if(args.moving_file.substr(args.moving_file.length()-2)!="gz"){
        cout<<"images must have nii.gz format\n";
        return -1;
    }

    cout<<"Starting linear reg. of "<<args.fixed_file.substr(split_fixed+1)<<" and "<<args.moving_file.substr(split_moving+1)<<"\n";
    cout<<"=============================================================\n";

    if(args.rigid){
        cout<<"Searching only for rigid (6 parameter) transform\n";
        RIGID=true;
    }

	qc=2;

	float alpha=1;
    //READ IMAGES and INITIALISE ARRAYS

    timeval time1,time2,time1a,time2a;

    RAND_SAMPLES=1; //fixed/efficient random sampling strategy

    float* im1; float* im1b;

    int M,N,O,P; //image dimensions

    //==ALWAYS ALLOCATE MEMORY FOR HEADER ===/
    char* header=new char[352];

    readNifti(args.fixed_file,im1b,header,M,N,O,P);
    image_m=M; image_n=N; image_o=O;

    readNifti(args.moving_file,im1,header,M,N,O,P);

    if(M!=image_m|N!=image_n|O!=image_o){
        cout<<"Inconsistent image sizes (must have same dimensions)\n";
        return -1;
    }

    int m=image_m; int n=image_n; int o=image_o; int sz=m*n*o;

    //assume we are working with CT scans (add 1024 HU)
    float thresholdF=-1024; float thresholdM=-1024;

    for(int i=0;i<sz;i++){
        im1b[i]-=thresholdF;
        im1[i]-=thresholdM;
    }

	float *warped1=new float[m*n*o];
    float *warped2=new float[m*n*o];

	int step1; int hw1; float quant1;

    vector<int> mind_step;
    for(int i=0;i<args.quantisation.size();i++){
        mind_step.push_back(floor(0.5f*(float)args.quantisation[i]+1.0f));
    }
    float* X=new float[4*4];

    float Xprev[16]={1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1};
    for(int i=0;i<16;i++){
        X[i]=Xprev[i];
    }

    uint64_t* im1_mind=new uint64_t[m*n*o];
    uint64_t* im1b_mind=new uint64_t[m*n*o];
    uint64_t* warped_mind=new uint64_t[m*n*o];

	gettimeofday(&time1a, NULL);
    float timeDataSmooth=0;
	//==========================================================================================
	//==========================================================================================
	float* bench=new float[6*args.levels];
	for(int level=0;level<args.levels;level++){
        quant1=args.quantisation[level];
        step1=args.grid_spacing[level];
        hw1=args.search_radius[level];

        float Xinv[16]; float Ident[16]={1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1};
        qrsolve(Xinv,Xprev,Ident,4,4);

        warpAffine(warped2,im1b,Xinv,m,n,o);
        warpAffine(warped1,im1,Xprev,m,n,o);

        float prev=mind_step[max(level-1,0)];
        float curr=mind_step[level];

        float timeMIND=0; float timeSmooth=0; float timeData=0; float timeTrans=0;

        if(level==0|prev!=curr){
            gettimeofday(&time1, NULL);
            descriptor(im1_mind,im1,m,n,o,mind_step[level]);//max(min(quant1,2.0f),1.0f)
            descriptor(im1b_mind,im1b,m,n,o,mind_step[level]);
            gettimeofday(&time2, NULL);
            timeMIND+=time2.tv_sec+time2.tv_usec/1e6-(time1.tv_sec+time1.tv_usec/1e6);
		}

		int len3=pow(hw1*2+1,3);
		int m1=m/step1; int n1=n/step1; int o1=o/step1; int sz1=m1*n1*o1;

        float* costall=new float[sz1*len3]; float* costall2=new float[sz1*len3];

        //cout<<"==========================================================\n";
		//cout<<"Level "<<level<<" grid="<<step1<<" hw="<<hw1<<" quant="<<quant1<<"\n";
		//cout<<"==========================================================\n";

        //FULL-REGISTRATION FORWARDS
        gettimeofday(&time1, NULL);
        gettimeofday(&time2, NULL);
		timeTrans+=time2.tv_sec+time2.tv_usec/1e6-(time1.tv_sec+time1.tv_usec/1e6);
        cout<<"T"<<flush;
        gettimeofday(&time1, NULL);
		descriptor(warped_mind,warped1,m,n,o,mind_step[level]);

        gettimeofday(&time2, NULL);
		timeMIND+=time2.tv_sec+time2.tv_usec/1e6-(time1.tv_sec+time1.tv_usec/1e6);
        cout<<"M"<<flush;
        gettimeofday(&time1, NULL);
        dataCostCL((unsigned long*)im1b_mind,(unsigned long*)warped_mind,costall,m,n,o,len3,step1,hw1,quant1,alpha,RAND_SAMPLES);
        gettimeofday(&time2, NULL);

		timeData+=time2.tv_sec+time2.tv_usec/1e6-(time1.tv_sec+time1.tv_usec/1e6);
        cout<<"D"<<flush;
        gettimeofday(&time1, NULL);
        gettimeofday(&time2, NULL);
		timeSmooth+=time2.tv_sec+time2.tv_usec/1e6-(time1.tv_sec+time1.tv_usec/1e6);
        cout<<"S"<<flush;

        //FULL-REGISTRATION BACKWARDS
        gettimeofday(&time1, NULL);
		gettimeofday(&time2, NULL);
		timeTrans+=time2.tv_sec+time2.tv_usec/1e6-(time1.tv_sec+time1.tv_usec/1e6);
        cout<<"T"<<flush;
        gettimeofday(&time1, NULL);
		descriptor(warped_mind,warped2,m,n,o,mind_step[level]);

        gettimeofday(&time2, NULL);
		timeMIND+=time2.tv_sec+time2.tv_usec/1e6-(time1.tv_sec+time1.tv_usec/1e6);
        cout<<"M"<<flush;
        gettimeofday(&time1, NULL);
        dataCostCL((unsigned long*)im1_mind,(unsigned long*)warped_mind,costall2,m,n,o,len3,step1,hw1,quant1,alpha,RAND_SAMPLES);
        gettimeofday(&time2, NULL);
		timeData+=time2.tv_sec+time2.tv_usec/1e6-(time1.tv_sec+time1.tv_usec/1e6);
        cout<<"DS\n"<<flush;
        gettimeofday(&time1, NULL);
        estimateAffine2(X,Xprev,im1b,im1,costall,costall2,step1,quant1,hw1);

        gettimeofday(&time2, NULL);
		timeSmooth+=time2.tv_sec+time2.tv_usec/1e6-(time1.tv_sec+time1.tv_usec/1e6);
        //cout<<"S"<<flush;

        printf("t: MIND=%2.2f, data=%2.2f, affine=%2.2f, speed=%2.2e dof/s\n",timeMIND,timeData,timeSmooth,2.0*(float)sz1*(float)len3/(timeData+timeSmooth));

        gettimeofday(&time1, NULL);

        gettimeofday(&time2, NULL);
        float timeMapping=time2.tv_sec+time2.tv_usec/1e6-(time1.tv_sec+time1.tv_usec/1e6);

        for(int i=0;i<16;i++){
            Xprev[i]=X[i];
        }

        timeDataSmooth+=(timeSmooth+timeData+timeMIND+timeTrans);

        delete costall; delete costall2;

	}
    delete im1_mind;
    delete im1b_mind;
	//==========================================================================================
	//==========================================================================================

    gettimeofday(&time2a, NULL);
	float timeALL=time2a.tv_sec+time2a.tv_usec/1e6-(time1a.tv_sec+time1a.tv_usec/1e6);

    string outputfile;
    outputfile.append(args.output_stem);
    outputfile.append("_matrix.txt");

    ofstream matfile;
    matfile.open(outputfile);

    for(int i=0;i<4;i++){
        matfile<<X[i]<<"  "<<X[i+4]<<"  "<<X[i+8]<<"  "<<X[i+12]<<"\n";

        printf("%+4.3f | %+4.3f | %+4.3f | %+4.3f \n",X[i],X[i+4],X[i+8],X[i+12]);
    }
    matfile.close();

    // if SEGMENTATION of moving image is provided APPLY SAME TRANSFORM
    if(args.segment){
        short* seg2;
        readNifti(args.moving_seg_file,seg2,header,M,N,O,P);

        float* zero=new float[sz];
        fill(zero,zero+sz,0.0f);

        short* segw=new short[sz];
        fill(segw,segw+sz,0);

        warpAffineS(segw,seg2,X,zero,zero,zero);

        string outputseg;
        outputseg.append(args.output_stem);
        outputseg.append("_deformed_seg.nii.gz");

        gzWriteSegment(outputseg,segw,header,m,n,o,1);
    }

	cout<<"Finished. Total time: "<<timeALL<<" sec. ("<<timeDataSmooth<<" sec. for MIND+data+affine+trans)\n";

	return 0;
}
<|endoftext|>


<commit_before>/*
* ECKCDSA (ISO/IEC 14888-3:2006/Cor.2:2009)
* (C) 2016 René Korthaus, Sirrix AG
*
* Botan is released under the Simplified BSD License (see license.txt)
*/

#include <botan/eckcdsa.h>
#include <botan/internal/pk_ops_impl.h>
#include <botan/keypair.h>
#include <botan/reducer.h>
#include <botan/emsa.h>
#include <botan/hash.h>

namespace Botan {

bool ECKCDSA_PrivateKey::check_key(RandomNumberGenerator& rng,
                                 bool strong) const
   {
   if(!public_point().on_the_curve())
      {
      return false;
      }

   if(!strong)
      {
      return true;
      }

   return KeyPair::signature_consistency_check(rng, *this, "EMSA1(SHA-256)");
   }

namespace {

/**
* ECKCDSA signature operation
*/
class ECKCDSA_Signature_Operation : public PK_Ops::Signature_with_EMSA
   {
   public:
      typedef ECKCDSA_PrivateKey Key_Type;

      ECKCDSA_Signature_Operation(const ECKCDSA_PrivateKey& eckcdsa,
                                const std::string& emsa) :
         PK_Ops::Signature_with_EMSA(emsa),
         m_order(eckcdsa.domain().get_order()),
         m_base_point(eckcdsa.domain().get_base_point(), m_order),
         m_x(eckcdsa.private_value()),
         m_mod_order(m_order),
         m_prefix()
         {
         const BigInt public_point_x = eckcdsa.public_point().get_affine_x();
         const BigInt public_point_y = eckcdsa.public_point().get_affine_y();

         m_prefix.resize(public_point_x.bytes() + public_point_y.bytes());
         public_point_x.binary_encode(m_prefix.data());
         public_point_y.binary_encode(&m_prefix[public_point_x.bytes()]);
         m_prefix.resize(HashFunction::create(hash_for_signature())->hash_block_size()); // use only the "hash input block size" leftmost bits
         }

      secure_vector<byte> raw_sign(const byte msg[], size_t msg_len,
                                   RandomNumberGenerator& rng) override;

      size_t message_parts() const override { return 2; }
      size_t message_part_size() const override { return m_order.bytes(); }
      size_t max_input_bits() const override { return m_order.bits(); }

      bool has_prefix() override { return true; }
      secure_vector<byte> message_prefix() const override { return m_prefix; }

   private:
      const BigInt& m_order;
      Blinded_Point_Multiply m_base_point;
      const BigInt& m_x;
      Modular_Reducer m_mod_order;
      secure_vector<byte> m_prefix;
   };

secure_vector<byte>
ECKCDSA_Signature_Operation::raw_sign(const byte msg[], size_t,
                                     RandomNumberGenerator& rng)
   {
   const BigInt k = BigInt::random_integer(rng, 1, m_order);
   const PointGFp k_times_P = m_base_point.blinded_multiply(k, rng);
   const BigInt k_times_P_x = k_times_P.get_affine_x();

   secure_vector<byte> to_be_hashed(k_times_P_x.bytes());
   k_times_P_x.binary_encode(to_be_hashed.data());

   std::unique_ptr<EMSA> emsa(m_emsa->clone());
   emsa->update(to_be_hashed.data(), to_be_hashed.size());
   secure_vector<byte> c = emsa->raw_data();
   c = emsa->encoding_of(c, max_input_bits(), rng);

   const BigInt r(c.data(), c.size());

   xor_buf(c, msg, c.size());
   BigInt w(c.data(), c.size());
   w = m_mod_order.reduce(w);

   const BigInt s = m_mod_order.multiply(m_x, k - w);
   BOTAN_ASSERT(s != 0, "invalid s");

   secure_vector<byte> output = BigInt::encode_1363(r, c.size());
   output += BigInt::encode_1363(s, m_order.bytes());
   return output;
   }

/**
* ECKCDSA verification operation
*/
class ECKCDSA_Verification_Operation : public PK_Ops::Verification_with_EMSA
   {
   public:
      typedef ECKCDSA_PublicKey Key_Type;

      ECKCDSA_Verification_Operation(const ECKCDSA_PublicKey& eckcdsa,
                                   const std::string& emsa) :
         PK_Ops::Verification_with_EMSA(emsa),
         m_base_point(eckcdsa.domain().get_base_point()),
         m_public_point(eckcdsa.public_point()),
         m_order(eckcdsa.domain().get_order()),
         m_mod_order(m_order),
         m_prefix()
         {
         const BigInt public_point_x = m_public_point.get_affine_x();
         const BigInt public_point_y = m_public_point.get_affine_y();

         m_prefix.resize(public_point_x.bytes() + public_point_y.bytes());
         public_point_x.binary_encode(&m_prefix[0]);
         public_point_y.binary_encode(&m_prefix[public_point_x.bytes()]);
         m_prefix.resize(HashFunction::create(hash_for_signature())->hash_block_size()); // use only the "hash input block size" leftmost bits
         }

      bool has_prefix() override { return true; }
      secure_vector<byte> message_prefix() const override { return m_prefix; }

      size_t message_parts() const override { return 2; }
      size_t message_part_size() const override { return m_order.bytes(); }
      size_t max_input_bits() const override { return m_order.bits(); }

      bool with_recovery() const override { return false; }

      bool verify(const byte msg[], size_t msg_len,
                  const byte sig[], size_t sig_len) override;
   private:
      const PointGFp& m_base_point;
      const PointGFp& m_public_point;
      const BigInt& m_order;
      // FIXME: should be offered by curve
      Modular_Reducer m_mod_order;
      secure_vector<byte> m_prefix;
   };

bool ECKCDSA_Verification_Operation::verify(const byte msg[], size_t,
                                           const byte sig[], size_t sig_len)
   {
   const std::unique_ptr<HashFunction> hash = HashFunction::create(hash_for_signature());
   //calculate size of r
   size_t size_r = std::min(hash -> output_length(), m_order.bytes());
   if(sig_len < size_r+m_order.bytes())
      {
      return false;
      }

   secure_vector<byte> r(sig, sig + size_r);

   // check that 0 < s < q
   const BigInt s(sig + size_r, m_order.bytes());

   if(s <= 0 || s >= m_order)
      {
      return false;
      }

   secure_vector<byte> r_xor_e(r);
   xor_buf(r_xor_e, msg, r.size());
   BigInt w(r_xor_e.data(), r_xor_e.size());
   w = m_mod_order.reduce(w);

   const PointGFp q = multi_exponentiate(m_base_point, w, m_public_point, s);
   const BigInt q_x = q.get_affine_x();
   secure_vector<byte> c(q_x.bytes());
   q_x.binary_encode(c.data());
   std::unique_ptr<EMSA> emsa(m_emsa->clone());
   emsa->update(c.data(), c.size());
   secure_vector<byte> v = emsa->raw_data();
   Null_RNG rng;
   v = emsa->encoding_of(v, max_input_bits(), rng);

   return (v == r);
   }

}

std::unique_ptr<PK_Ops::Verification>
ECKCDSA_PublicKey::create_verification_op(const std::string& params,
                                         const std::string& provider) const
   {
   if(provider == "base" || provider.empty())
      return std::unique_ptr<PK_Ops::Verification>(new ECKCDSA_Verification_Operation(*this, params));
   throw Provider_Not_Found(algo_name(), provider);
   }

std::unique_ptr<PK_Ops::Signature>
ECKCDSA_PrivateKey::create_signature_op(RandomNumberGenerator& /*rng*/,
                                        const std::string& params,
                                        const std::string& provider) const
   {
   if(provider == "base" || provider.empty())
      return std::unique_ptr<PK_Ops::Signature>(new ECKCDSA_Signature_Operation(*this, params));
   throw Provider_Not_Found(algo_name(), provider);
   }

}
<commit_msg>Fix ECKCDSA verification problem<commit_after>/*
* ECKCDSA (ISO/IEC 14888-3:2006/Cor.2:2009)
* (C) 2016 René Korthaus, Sirrix AG
*
* Botan is released under the Simplified BSD License (see license.txt)
*/

#include <botan/eckcdsa.h>
#include <botan/internal/pk_ops_impl.h>
#include <botan/keypair.h>
#include <botan/reducer.h>
#include <botan/emsa.h>
#include <botan/hash.h>

namespace Botan {

bool ECKCDSA_PrivateKey::check_key(RandomNumberGenerator& rng,
                                 bool strong) const
   {
   if(!public_point().on_the_curve())
      {
      return false;
      }

   if(!strong)
      {
      return true;
      }

   return KeyPair::signature_consistency_check(rng, *this, "EMSA1(SHA-256)");
   }

namespace {

/**
* ECKCDSA signature operation
*/
class ECKCDSA_Signature_Operation : public PK_Ops::Signature_with_EMSA
   {
   public:
      typedef ECKCDSA_PrivateKey Key_Type;

      ECKCDSA_Signature_Operation(const ECKCDSA_PrivateKey& eckcdsa,
                                const std::string& emsa) :
         PK_Ops::Signature_with_EMSA(emsa),
         m_order(eckcdsa.domain().get_order()),
         m_base_point(eckcdsa.domain().get_base_point(), m_order),
         m_x(eckcdsa.private_value()),
         m_mod_order(m_order),
         m_prefix()
         {
         const BigInt public_point_x = eckcdsa.public_point().get_affine_x();
         const BigInt public_point_y = eckcdsa.public_point().get_affine_y();

         m_prefix.resize(public_point_x.bytes() + public_point_y.bytes());
         public_point_x.binary_encode(m_prefix.data());
         public_point_y.binary_encode(&m_prefix[public_point_x.bytes()]);
         m_prefix.resize(HashFunction::create(hash_for_signature())->hash_block_size()); // use only the "hash input block size" leftmost bits
         }

      secure_vector<byte> raw_sign(const byte msg[], size_t msg_len,
                                   RandomNumberGenerator& rng) override;

      size_t message_parts() const override { return 2; }
      size_t message_part_size() const override { return m_order.bytes(); }
      size_t max_input_bits() const override { return m_order.bits(); }

      bool has_prefix() override { return true; }
      secure_vector<byte> message_prefix() const override { return m_prefix; }

   private:
      const BigInt& m_order;
      Blinded_Point_Multiply m_base_point;
      const BigInt& m_x;
      Modular_Reducer m_mod_order;
      secure_vector<byte> m_prefix;
   };

secure_vector<byte>
ECKCDSA_Signature_Operation::raw_sign(const byte msg[], size_t,
                                     RandomNumberGenerator& rng)
   {
   const BigInt k = BigInt::random_integer(rng, 1, m_order);
   const PointGFp k_times_P = m_base_point.blinded_multiply(k, rng);
   const BigInt k_times_P_x = k_times_P.get_affine_x();

   secure_vector<byte> to_be_hashed(k_times_P_x.bytes());
   k_times_P_x.binary_encode(to_be_hashed.data());

   std::unique_ptr<EMSA> emsa(m_emsa->clone());
   emsa->update(to_be_hashed.data(), to_be_hashed.size());
   secure_vector<byte> c = emsa->raw_data();
   c = emsa->encoding_of(c, max_input_bits(), rng);

   const BigInt r(c.data(), c.size());

   xor_buf(c, msg, c.size());
   BigInt w(c.data(), c.size());
   w = m_mod_order.reduce(w);

   const BigInt s = m_mod_order.multiply(m_x, k - w);
   BOTAN_ASSERT(s != 0, "invalid s");

   secure_vector<byte> output = BigInt::encode_1363(r, c.size());
   output += BigInt::encode_1363(s, m_order.bytes());
   return output;
   }

/**
* ECKCDSA verification operation
*/
class ECKCDSA_Verification_Operation : public PK_Ops::Verification_with_EMSA
   {
   public:
      typedef ECKCDSA_PublicKey Key_Type;

      ECKCDSA_Verification_Operation(const ECKCDSA_PublicKey& eckcdsa,
                                   const std::string& emsa) :
         PK_Ops::Verification_with_EMSA(emsa),
         m_base_point(eckcdsa.domain().get_base_point()),
         m_public_point(eckcdsa.public_point()),
         m_order(eckcdsa.domain().get_order()),
         m_mod_order(m_order),
         m_prefix()
         {
         const BigInt public_point_x = m_public_point.get_affine_x();
         const BigInt public_point_y = m_public_point.get_affine_y();

         m_prefix.resize(public_point_x.bytes() + public_point_y.bytes());
         public_point_x.binary_encode(&m_prefix[0]);
         public_point_y.binary_encode(&m_prefix[public_point_x.bytes()]);
         m_prefix.resize(HashFunction::create(hash_for_signature())->hash_block_size()); // use only the "hash input block size" leftmost bits
         }

      bool has_prefix() override { return true; }
      secure_vector<byte> message_prefix() const override { return m_prefix; }

      size_t message_parts() const override { return 2; }
      size_t message_part_size() const override { return m_order.bytes(); }
      size_t max_input_bits() const override { return m_order.bits(); }

      bool with_recovery() const override { return false; }

      bool verify(const byte msg[], size_t msg_len,
                  const byte sig[], size_t sig_len) override;
   private:
      const PointGFp& m_base_point;
      const PointGFp& m_public_point;
      const BigInt& m_order;
      // FIXME: should be offered by curve
      Modular_Reducer m_mod_order;
      secure_vector<byte> m_prefix;
   };

bool ECKCDSA_Verification_Operation::verify(const byte msg[], size_t,
                                           const byte sig[], size_t sig_len)
   {
   const std::unique_ptr<HashFunction> hash = HashFunction::create(hash_for_signature());
   //calculate size of r
   size_t size_r = std::min(hash -> output_length(), m_order.bytes());
   if(sig_len != size_r+m_order.bytes())
      {
      return false;
      }

   secure_vector<byte> r(sig, sig + size_r);

   // check that 0 < s < q
   const BigInt s(sig + size_r, m_order.bytes());

   if(s <= 0 || s >= m_order)
      {
      return false;
      }

   secure_vector<byte> r_xor_e(r);
   xor_buf(r_xor_e, msg, r.size());
   BigInt w(r_xor_e.data(), r_xor_e.size());
   w = m_mod_order.reduce(w);

   const PointGFp q = multi_exponentiate(m_base_point, w, m_public_point, s);
   const BigInt q_x = q.get_affine_x();
   secure_vector<byte> c(q_x.bytes());
   q_x.binary_encode(c.data());
   std::unique_ptr<EMSA> emsa(m_emsa->clone());
   emsa->update(c.data(), c.size());
   secure_vector<byte> v = emsa->raw_data();
   Null_RNG rng;
   v = emsa->encoding_of(v, max_input_bits(), rng);

   return (v == r);
   }

}

std::unique_ptr<PK_Ops::Verification>
ECKCDSA_PublicKey::create_verification_op(const std::string& params,
                                         const std::string& provider) const
   {
   if(provider == "base" || provider.empty())
      return std::unique_ptr<PK_Ops::Verification>(new ECKCDSA_Verification_Operation(*this, params));
   throw Provider_Not_Found(algo_name(), provider);
   }

std::unique_ptr<PK_Ops::Signature>
ECKCDSA_PrivateKey::create_signature_op(RandomNumberGenerator& /*rng*/,
                                        const std::string& params,
                                        const std::string& provider) const
   {
   if(provider == "base" || provider.empty())
      return std::unique_ptr<PK_Ops::Signature>(new ECKCDSA_Signature_Operation(*this, params));
   throw Provider_Not_Found(algo_name(), provider);
   }

}
<|endoftext|>


<commit_before>/*
 * File:   WindMap.cpp
 * Author: maxence
 *
 * Created on 07 novembre 2014, 13:39
 */
#include "shared/map/WindMap.h"

#include <iostream>
#include <SFML/System/Vector2.hpp>

#include "shared/ValueNoise.h"

const int WindMap::maxStrength = 64;
const int WindMap::minStrength = 16;

sf::Packet& operator<<(sf::Packet& packet, const WindMap& map) {
    return packet << map.getHeader();
}

WindMap::WindMap() : m_header(0, 0), m_container(nullptr) {

}

WindMap::WindMap(const MapHeader &header)
: m_header(header)
, m_container(nullptr) {
    if(m_header.getWidth() == 0 || m_header.getHeight() == 0)
        return;
    int width = header.getWidth();
    int height = header.getHeight();

    ValueNoise::GenerateValues(getSeed());

    m_container = new Wind*[height];

    for (int i = 0; i < height; ++i) {
        m_container[i] = new Wind[width];
    }

    float invWidth = 1.f / width, invHeight = 1.f / height;

    for (int i = 0; i < width; ++i) {
        for (int j = 0; j < height; ++j) {
            sf::Vector2f pnoise(i * invWidth, j * invHeight);
            float nDirection = ValueNoise::Eval(sf::Vector2f(pnoise.x * 20.0f, pnoise.y * 20.0f));
            //            float nDirection =45.0f/360.0f;
            float nForce = ValueNoise::Eval(sf::Vector2f(pnoise.x * 40.0f, pnoise.y * 40.0f));
            m_container[i][j] = Wind(nDirection * 360.0f, nForce * (maxStrength - minStrength) + minStrength);
        }
    }
}

WindMap::~WindMap() {
//    if (m_container != nullptr) { // @TODO
//        for (int i = 0; i < getHeight(); ++i) {
//            delete m_container[i];
//        }
//        delete m_container;
//    }
}

int WindMap::getSize() const {
    return m_header.getSize();
}

int WindMap::getWidth() const {
    return m_header.getWidth();
}

int WindMap::getHeight() const {
    return m_header.getHeight();
}

int WindMap::getSeed() const {
    return m_header.getSeed();
}

const MapHeader& WindMap::getHeader() const {
    return m_header;
}

MapHeader& WindMap::getHeader() {
    return m_header;
}
<commit_msg>Change wind direction generation<commit_after>/*
 * File:   WindMap.cpp
 * Author: maxence
 *
 * Created on 07 novembre 2014, 13:39
 */
#include "shared/map/WindMap.h"

#include <iostream>
#include <SFML/System/Vector2.hpp>

#include "shared/ValueNoise.h"

const int WindMap::maxStrength = 64;
const int WindMap::minStrength = 32;

sf::Packet& operator<<(sf::Packet& packet, const WindMap& map) {
    return packet << map.getHeader();
}

WindMap::WindMap() : m_header(0, 0), m_container(nullptr) {

}

WindMap::WindMap(const MapHeader &header)
: m_header(header)
, m_container(nullptr) {
    if(m_header.getWidth() == 0 || m_header.getHeight() == 0)
        return;
    int width = header.getWidth();
    int height = header.getHeight();

    ValueNoise::GenerateValues(getSeed());

    m_container = new Wind*[height];

    for (int i = 0; i < height; ++i) {
        m_container[i] = new Wind[width];
    }

    float invWidth = 1.f / width, invHeight = 1.f / height;
    float mainDir = ValueNoise::Eval(sf::Vector2f(0.0f,0.0f));

    for (int i = 0; i < width; ++i) {
        for (int j = 0; j < height; ++j) {
            sf::Vector2f pnoise(i * invWidth, j * invHeight);
            float nDirection = ValueNoise::Eval(sf::Vector2f(pnoise.x * 5.0f, pnoise.y * 5.0f));
            //            float nDirection =45.0f/360.0f;
            float nForce = ValueNoise::Eval(sf::Vector2f(pnoise.x * 40.0f, pnoise.y * 40.0f));
            m_container[i][j] = Wind(mainDir + ( 120.0f * (nDirection - 0.5f)), nForce * (maxStrength - minStrength) + minStrength);
        }
    }
}

WindMap::~WindMap() {
//    if (m_container != nullptr) { // @TODO
//        for (int i = 0; i < getHeight(); ++i) {
//            delete m_container[i];
//        }
//        delete m_container;
//    }
}

int WindMap::getSize() const {
    return m_header.getSize();
}

int WindMap::getWidth() const {
    return m_header.getWidth();
}

int WindMap::getHeight() const {
    return m_header.getHeight();
}

int WindMap::getSeed() const {
    return m_header.getSeed();
}

const MapHeader& WindMap::getHeader() const {
    return m_header;
}

MapHeader& WindMap::getHeader() {
    return m_header;
}
<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * 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.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sdext.hxx"

#include "pppoptimizerdialog.hxx"
#include "optimizerdialog.hxx"

using namespace ::rtl;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::util;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::frame;
using namespace ::com::sun::star::beans;

#define SERVICE_NAME "com.sun.star.comp.SunPresentationMinimizer"
#include <rtl/ustrbuf.hxx>

// ----------------------
// - PPPOptimizerDialog -
// ----------------------

PPPOptimizerDialog::PPPOptimizerDialog( const Reference< XComponentContext > &rxMSF ) :
    mxMSF( rxMSF ),
    mpOptimizerDialog( NULL )
{
}

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

PPPOptimizerDialog::~PPPOptimizerDialog()
{
}

// -----------------------------------------------------------------------------
// XInitialization
// -----------------------------------------------------------------------------

void SAL_CALL PPPOptimizerDialog::initialize( const Sequence< Any >& aArguments )
    throw ( Exception, RuntimeException )
{
    if( aArguments.getLength() != 1 )
        throw IllegalArgumentException();

    aArguments[ 0 ] >>= mxFrame;
    if ( mxFrame.is() )
        mxController = mxFrame->getController();
}

// -----------------------------------------------------------------------------
// XServiceInfo
// -----------------------------------------------------------------------------

OUString SAL_CALL PPPOptimizerDialog::getImplementationName()
    throw (RuntimeException)
{
    return PPPOptimizerDialog_getImplementationName();
}

sal_Bool SAL_CALL PPPOptimizerDialog::supportsService( const OUString& ServiceName )
    throw ( RuntimeException )
{
    return ServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( SERVICE_NAME ) );
}

Sequence< OUString > SAL_CALL PPPOptimizerDialog::getSupportedServiceNames()
    throw (RuntimeException)
{
    return PPPOptimizerDialog_getSupportedServiceNames();
}

// -----------------------------------------------------------------------------
// XDispatchProvider
// -----------------------------------------------------------------------------

Reference< com::sun::star::frame::XDispatch > SAL_CALL PPPOptimizerDialog::queryDispatch(
    const URL& aURL, const ::rtl::OUString& /* aTargetFrameName */, sal_Int32 /* nSearchFlags */ ) throw( RuntimeException )
{
    Reference < XDispatch > xRet;
    if ( aURL.Protocol.compareToAscii( "vnd.com.sun.star.comp.SunPresentationMinimizer:" ) == 0 )
        xRet = this;

    return xRet;
}

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

Sequence< Reference< com::sun::star::frame::XDispatch > > SAL_CALL PPPOptimizerDialog::queryDispatches(
    const Sequence< com::sun::star::frame::DispatchDescriptor >& aDescripts ) throw( RuntimeException )
{
    Sequence< Reference< com::sun::star::frame::XDispatch> > aReturn( aDescripts.getLength() );
    Reference< com::sun::star::frame::XDispatch>* pReturn = aReturn.getArray();
    const com::sun::star::frame::DispatchDescriptor* pDescripts = aDescripts.getConstArray();
    for (sal_Int16 i = 0; i < aDescripts.getLength(); ++i, ++pReturn, ++pDescripts )
    {
        *pReturn = queryDispatch( pDescripts->FeatureURL, pDescripts->FrameName, pDescripts->SearchFlags );
    }
    return aReturn;
}

// -----------------------------------------------------------------------------
// XDispatch
// -----------------------------------------------------------------------------

void SAL_CALL PPPOptimizerDialog::dispatch( const URL& rURL,
                                            const Sequence< PropertyValue >& rArguments )
    throw( RuntimeException )
{

    if ( mxController.is() && ( rURL.Protocol.compareToAscii( "vnd.com.sun.star.comp.SunPresentationMinimizer:" ) == 0 ) )
    {
        if ( rURL.Path.compareToAscii( "execute" ) == 0 )
        {
            try
            {
                sal_Int64 nFileSizeSource,nFileSizeDest = 0;
                mpOptimizerDialog = new OptimizerDialog( mxMSF, mxFrame, this );
                mpOptimizerDialog->execute();

                const Any* pVal( mpOptimizerDialog->maStats.GetStatusValue( TK_FileSizeSource ) );
                if ( pVal )
                    *pVal >>= nFileSizeSource;
                pVal = mpOptimizerDialog->maStats.GetStatusValue( TK_FileSizeDestination );
                if ( pVal )
                    *pVal >>= nFileSizeDest;

                if ( nFileSizeSource && nFileSizeDest )
                {
                    rtl::OUStringBuffer sBuf( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Your Presentation has been minimized from:")) );
                    sBuf.append( rtl::OUString::valueOf( nFileSizeSource >> 10 ) );
                    sBuf.append( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("KB to ")) );
                    sBuf.append( rtl::OUString::valueOf( nFileSizeDest >> 10 ) );
                    sBuf.append( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("KB.")) );
                    OUString sResult( sBuf.makeStringAndClear() );
//                  mpOptimizerDialog->showMessageBox( sResult, sResult, sal_False );
                }
                delete mpOptimizerDialog, mpOptimizerDialog = NULL;
            }
            catch( ... )
            {

            }
        }
        else if ( rURL.Path.compareToAscii( "statusupdate" ) == 0 )
        {
            if ( mpOptimizerDialog )
                mpOptimizerDialog->UpdateStatus( rArguments );
        }
    }
}

//===============================================
void SAL_CALL PPPOptimizerDialog::addStatusListener( const Reference< XStatusListener >&, const URL& )
    throw( RuntimeException )
{
    // TODO
    // OSL_ENSURE( sal_False, "PPPOptimizerDialog::addStatusListener()\nNot implemented yet!" );
}

//===============================================
void SAL_CALL PPPOptimizerDialog::removeStatusListener( const Reference< XStatusListener >&, const URL& )
    throw( RuntimeException )
{
    // TODO
    // OSL_ENSURE( sal_False, "PPPOptimizerDialog::removeStatusListener()\nNot implemented yet!" );
}

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

OUString PPPOptimizerDialog_getImplementationName()
{
    return OUString ( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.comp.SunPresentationMinimizerImp" ) );
}

Sequence< OUString > PPPOptimizerDialog_getSupportedServiceNames()
{
    Sequence < OUString > aRet(1);
    OUString* pArray = aRet.getArray();
    pArray[0] =  OUString ( RTL_CONSTASCII_USTRINGPARAM( SERVICE_NAME ) );
    return aRet;
}

Reference< XInterface > PPPOptimizerDialog_createInstance( const Reference< XComponentContext > & rSMgr)
    throw( Exception )
{
    return (cppu::OWeakObject*) new PPPOptimizerDialog( rSMgr );
}

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

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>Correct variable initialization for 0b58d1d635b33148e6765eb35016b0fb43f214b3<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * 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.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sdext.hxx"

#include "pppoptimizerdialog.hxx"
#include "optimizerdialog.hxx"

using namespace ::rtl;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::util;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::frame;
using namespace ::com::sun::star::beans;

#define SERVICE_NAME "com.sun.star.comp.SunPresentationMinimizer"
#include <rtl/ustrbuf.hxx>

// ----------------------
// - PPPOptimizerDialog -
// ----------------------

PPPOptimizerDialog::PPPOptimizerDialog( const Reference< XComponentContext > &rxMSF ) :
    mxMSF( rxMSF ),
    mpOptimizerDialog( NULL )
{
}

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

PPPOptimizerDialog::~PPPOptimizerDialog()
{
}

// -----------------------------------------------------------------------------
// XInitialization
// -----------------------------------------------------------------------------

void SAL_CALL PPPOptimizerDialog::initialize( const Sequence< Any >& aArguments )
    throw ( Exception, RuntimeException )
{
    if( aArguments.getLength() != 1 )
        throw IllegalArgumentException();

    aArguments[ 0 ] >>= mxFrame;
    if ( mxFrame.is() )
        mxController = mxFrame->getController();
}

// -----------------------------------------------------------------------------
// XServiceInfo
// -----------------------------------------------------------------------------

OUString SAL_CALL PPPOptimizerDialog::getImplementationName()
    throw (RuntimeException)
{
    return PPPOptimizerDialog_getImplementationName();
}

sal_Bool SAL_CALL PPPOptimizerDialog::supportsService( const OUString& ServiceName )
    throw ( RuntimeException )
{
    return ServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( SERVICE_NAME ) );
}

Sequence< OUString > SAL_CALL PPPOptimizerDialog::getSupportedServiceNames()
    throw (RuntimeException)
{
    return PPPOptimizerDialog_getSupportedServiceNames();
}

// -----------------------------------------------------------------------------
// XDispatchProvider
// -----------------------------------------------------------------------------

Reference< com::sun::star::frame::XDispatch > SAL_CALL PPPOptimizerDialog::queryDispatch(
    const URL& aURL, const ::rtl::OUString& /* aTargetFrameName */, sal_Int32 /* nSearchFlags */ ) throw( RuntimeException )
{
    Reference < XDispatch > xRet;
    if ( aURL.Protocol.compareToAscii( "vnd.com.sun.star.comp.SunPresentationMinimizer:" ) == 0 )
        xRet = this;

    return xRet;
}

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

Sequence< Reference< com::sun::star::frame::XDispatch > > SAL_CALL PPPOptimizerDialog::queryDispatches(
    const Sequence< com::sun::star::frame::DispatchDescriptor >& aDescripts ) throw( RuntimeException )
{
    Sequence< Reference< com::sun::star::frame::XDispatch> > aReturn( aDescripts.getLength() );
    Reference< com::sun::star::frame::XDispatch>* pReturn = aReturn.getArray();
    const com::sun::star::frame::DispatchDescriptor* pDescripts = aDescripts.getConstArray();
    for (sal_Int16 i = 0; i < aDescripts.getLength(); ++i, ++pReturn, ++pDescripts )
    {
        *pReturn = queryDispatch( pDescripts->FeatureURL, pDescripts->FrameName, pDescripts->SearchFlags );
    }
    return aReturn;
}

// -----------------------------------------------------------------------------
// XDispatch
// -----------------------------------------------------------------------------

void SAL_CALL PPPOptimizerDialog::dispatch( const URL& rURL,
                                            const Sequence< PropertyValue >& rArguments )
    throw( RuntimeException )
{

    if ( mxController.is() && ( rURL.Protocol.compareToAscii( "vnd.com.sun.star.comp.SunPresentationMinimizer:" ) == 0 ) )
    {
        if ( rURL.Path.compareToAscii( "execute" ) == 0 )
        {
            try
            {
                sal_Int64 nFileSizeSource = 0;
                sal_Int64 nFileSizeDest = 0;
                mpOptimizerDialog = new OptimizerDialog( mxMSF, mxFrame, this );
                mpOptimizerDialog->execute();

                const Any* pVal( mpOptimizerDialog->maStats.GetStatusValue( TK_FileSizeSource ) );
                if ( pVal )
                    *pVal >>= nFileSizeSource;
                pVal = mpOptimizerDialog->maStats.GetStatusValue( TK_FileSizeDestination );
                if ( pVal )
                    *pVal >>= nFileSizeDest;

                if ( nFileSizeSource && nFileSizeDest )
                {
                    rtl::OUStringBuffer sBuf( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Your Presentation has been minimized from:")) );
                    sBuf.append( rtl::OUString::valueOf( nFileSizeSource >> 10 ) );
                    sBuf.append( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("KB to ")) );
                    sBuf.append( rtl::OUString::valueOf( nFileSizeDest >> 10 ) );
                    sBuf.append( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("KB.")) );
                    OUString sResult( sBuf.makeStringAndClear() );
//                  mpOptimizerDialog->showMessageBox( sResult, sResult, sal_False );
                }
                delete mpOptimizerDialog, mpOptimizerDialog = NULL;
            }
            catch( ... )
            {

            }
        }
        else if ( rURL.Path.compareToAscii( "statusupdate" ) == 0 )
        {
            if ( mpOptimizerDialog )
                mpOptimizerDialog->UpdateStatus( rArguments );
        }
    }
}

//===============================================
void SAL_CALL PPPOptimizerDialog::addStatusListener( const Reference< XStatusListener >&, const URL& )
    throw( RuntimeException )
{
    // TODO
    // OSL_ENSURE( sal_False, "PPPOptimizerDialog::addStatusListener()\nNot implemented yet!" );
}

//===============================================
void SAL_CALL PPPOptimizerDialog::removeStatusListener( const Reference< XStatusListener >&, const URL& )
    throw( RuntimeException )
{
    // TODO
    // OSL_ENSURE( sal_False, "PPPOptimizerDialog::removeStatusListener()\nNot implemented yet!" );
}

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

OUString PPPOptimizerDialog_getImplementationName()
{
    return OUString ( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.comp.SunPresentationMinimizerImp" ) );
}

Sequence< OUString > PPPOptimizerDialog_getSupportedServiceNames()
{
    Sequence < OUString > aRet(1);
    OUString* pArray = aRet.getArray();
    pArray[0] =  OUString ( RTL_CONSTASCII_USTRINGPARAM( SERVICE_NAME ) );
    return aRet;
}

Reference< XInterface > PPPOptimizerDialog_createInstance( const Reference< XComponentContext > & rSMgr)
    throw( Exception )
{
    return (cppu::OWeakObject*) new PPPOptimizerDialog( rSMgr );
}

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

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>


<commit_before>/// @file sql_well_serialize.cpp
/// @brief Serialization implementations for sql_well
/// @author uentity
/// @version
/// @date 20.01.2012
/// @copyright This source code is released under the terms of
///            the BSD License. See LICENSE for more details.

#include "bs_bos_core_data_storage_stdafx.h"

#include "bs_serialize.h"
#include "sql_well.h"

#include <boost/serialization/string.hpp>

#include <boost/uuid/uuid.hpp>
//#include <boost/uuid/string_generator.hpp>
#include <boost/uuid/random_generator.hpp>
#include <boost/uuid/uuid_io.hpp>

#include <stdio.h>

// path separator
#ifdef UNIX
#define PATHSEP '/'
#else
#define PATHSEP '\\'
#endif

using namespace blue_sky;
namespace bu = boost::uuids;
namespace boser = boost::serialization;

BLUE_SKY_CLASS_SRZ_FCN_BEGIN(save, blue_sky::sql_well)
	// save file_name
	ar << t.file_name;

	// check db has an associated filename
	// strangely there is no such API function though it is documented
	//std::string db_fname(sqlite3_db_filename(t.db, "main"));
	std::string db_fname, prj_path, prj_name, db_basename;
	// check if hdm serializer saved filename for us
	kernel::idx_dt_ptr kdt = BS_KERNEL.pert_idx_dt(BS_KERNEL.find_type("hdm").td_);
	if(kdt && kdt->size< std::string >()) {
		prj_path = kdt->ss< std::string >(0);
		prj_name = kdt->ss< std::string >(1);
		db_basename = prj_name;
		// if we should make a deep copy of well pool - add given suffix to filename
		if(kdt->size< std::string >() > 2)
			db_basename += std::string("_") + kdt->ss< std::string >(2);
		db_basename += "_well_pool.db";
		db_fname = prj_path + PATHSEP + db_basename;
	}
	else {
		db_basename = t.file_name;
		db_fname = t.file_name;
	}

	// generate uuid that is part of filename
	if(db_basename.empty()) {
		bu::uuid db_uuid = bu::random_generator()();
		db_basename = bu::to_string(db_uuid) + "_well_pool.db";
		db_fname = std::string("file:") + db_basename;
	}

	// flag indicating whether we should backup db
	bool do_write_db = true;
	// check if database is open
	int cur_s, hiwtr, opres = SQLITE_OK + 1;
	sqlite3* src_db = t.db;
	if(src_db) {
		opres = sqlite3_db_status(src_db, 0, &cur_s, &hiwtr, 0);
		if(opres != SQLITE_OK) {
			// probably db is closed or not open or whatever
			// try to open it using contained file_name
			// or db_basename
			if(t.file_name.size()) {
				opres = sqlite3_open(t.file_name.c_str(), &src_db);
				if(opres != SQLITE_OK)
					opres = sqlite3_open(db_fname.c_str(), &src_db);
				if(opres != SQLITE_OK) {
					sqlite3_close(src_db);
					do_write_db = false;
				}
			}
		}
	}
	else
		do_write_db = false;

	ar << do_write_db;
	// if db not open now, we're done
	if(!do_write_db)
		return;

	// save basename first
	ar << db_basename;
	ar << db_fname;

	// open db for backup
	sqlite3* save_db = NULL;
	sqlite3_backup* save_bu = NULL;
	opres = sqlite3_open(db_fname.c_str(), &save_db);
	// and prepare backup process
	if(opres == SQLITE_OK)
		save_bu = sqlite3_backup_init(save_db, "main", src_db, "main");
	if(!save_bu) {
		// probably source & dest db are the same
		sqlite3_close(save_db);
		return;
	}

	// copy data to save_db
	while((opres = sqlite3_backup_step(save_bu, -1)) == SQLITE_OK) {}
	sqlite3_backup_finish(save_bu);
	sqlite3_close(save_db);
	// SQLITE_BUSY returned if we're trying to backup into source db
	if(opres != SQLITE_DONE && opres != SQLITE_BUSY) {
		// if error happens - kill db file
		::remove(db_fname.c_str());
	}

	// save flag that db backup was successful and filename of backup db
	//do_write_db = true;
	//ar << do_write_db;
BLUE_SKY_CLASS_SRZ_FCN_END

BLUE_SKY_CLASS_SRZ_FCN_BEGIN(load, blue_sky::sql_well)
	// load filename
	ar >> (std::string&)t.file_name;
	// and flag if we should restore db
	bool do_load_db;
	ar >> do_load_db;
	if(!do_load_db) return;

	// backup db handle
	sqlite3* bu_db;
	int opres;

	// load backup db fname
	std::string db_basename, db_fname;
	ar >> db_basename >> db_fname;

	// check if hdm serializer saved project path for us
	kernel::idx_dt_ptr kdt = BS_KERNEL.pert_idx_dt(BS_KERNEL.find_type("hdm").td_);
	if(kdt && kdt->size< std::string >()) {
		std::string prj_path = kdt->ss< std::string >(0);
		// try to open db relative to project path
		std::string db_relname = prj_path + PATHSEP + db_basename;
		opres = sqlite3_open(db_relname.c_str(), &bu_db);
		if(opres == SQLITE_OK) {
			// save handle to open db
			t.db = bu_db;
			return;
		}
		else
			sqlite3_close(bu_db);
	}

	opres = sqlite3_open(db_fname.c_str(), &bu_db);
	if(opres == SQLITE_OK) {
		// just save handle to db into sql_well and we're done
		t.db = bu_db;
		return;
	}
	// finally try to open db from stored path t.file_name
	sqlite3_close(bu_db);
	opres = sqlite3_open(t.file_name.c_str(), &bu_db);
	if(opres == SQLITE_OK)
		t.db = bu_db;
	else
		sqlite3_close(bu_db);
BLUE_SKY_CLASS_SRZ_FCN_END

// generate serialize() function that uses save & load
//BLUE_SKY_CLASS_SERIALIZE_SPLIT(blue_sky::sql_well)
BLUE_SKY_CLASS_SRZ_FCN_BEGIN(serialize, blue_sky::sql_well)
	// register conversion to base iface
	boser::bs_void_cast_register(
		static_cast< sql_well* >(NULL),
		static_cast< well_pool_iface* >(NULL)
	);
	// split into save/load
	boser::split_free(ar, t, version);
BLUE_SKY_CLASS_SRZ_FCN_END

// instantiate serialization code
BLUE_SKY_TYPE_SERIALIZE_DECL(blue_sky::sql_well)
BLUE_SKY_TYPE_SERIALIZE_IMPL(blue_sky::sql_well)

<commit_msg>SQW: revert and refactor commit 39ddb619f6440d00e7bc874fd4501ba506275b71<commit_after>/// @file sql_well_serialize.cpp
/// @brief Serialization implementations for sql_well
/// @author uentity
/// @version
/// @date 20.01.2012
/// @copyright This source code is released under the terms of
///            the BSD License. See LICENSE for more details.

#include "bs_bos_core_data_storage_stdafx.h"

#include "bs_serialize.h"
#include "sql_well.h"

#include <boost/serialization/string.hpp>

#include <boost/uuid/uuid.hpp>
//#include <boost/uuid/string_generator.hpp>
#include <boost/uuid/random_generator.hpp>
#include <boost/uuid/uuid_io.hpp>

#include <stdio.h>

// path separator
#ifdef UNIX
#define PATHSEP '/'
#else
#define PATHSEP '\\'
#endif

using namespace blue_sky;
namespace bu = boost::uuids;
namespace boser = boost::serialization;

BLUE_SKY_CLASS_SRZ_FCN_BEGIN(save, blue_sky::sql_well)
	// save file_name
	ar << t.file_name;

	// check db has an associated filename
	// strangely there is no such API function though it is documented
	//std::string db_fname(sqlite3_db_filename(t.db, "main"));
	std::string db_fname, prj_path, prj_name, db_basename;
	// check if hdm serializer saved filename for us
	kernel::idx_dt_ptr kdt = BS_KERNEL.pert_idx_dt(BS_KERNEL.find_type("hdm").td_);
	if(kdt && kdt->size< std::string >()) {
		prj_path = kdt->ss< std::string >(0);
		prj_name = kdt->ss< std::string >(1);
		db_basename = prj_name;
		// if we should make a deep copy of well pool - add given suffix to filename
		if(kdt->size< std::string >() > 2)
			db_basename += std::string("_") + kdt->ss< std::string >(2);
		db_basename += "_well_pool.db";
		db_fname = prj_path + PATHSEP + db_basename;
	}
	else {
		db_basename = t.file_name;
		db_fname = t.file_name;
	}

	// generate uuid that is part of filename
	if(db_basename.empty()) {
		bu::uuid db_uuid = bu::random_generator()();
		db_basename = bu::to_string(db_uuid) + "_well_pool.db";
		db_fname = std::string("file:") + db_basename;
	}

	// flag indicating whether we should backup db
	bool do_write_db = true;
	// check if database is open
	int cur_s, hiwtr, opres = SQLITE_OK + 1;
	sqlite3* src_db = t.db;
	if(src_db)
		opres = sqlite3_db_status(src_db, 0, &cur_s, &hiwtr, 0);
	if(opres != SQLITE_OK) {
		// probably db is closed or not open or whatever
		// try to open it using contained file_name
		// or db_basename
		if(t.file_name.size())
			opres = sqlite3_open(t.file_name.c_str(), &src_db);
		if(opres != SQLITE_OK)
			opres = sqlite3_open(db_fname.c_str(), &src_db);
		if(opres != SQLITE_OK) {
			sqlite3_close(src_db);
			do_write_db = false;
		}
	}

	ar << do_write_db;
	// if db not open now, we're done
	if(!do_write_db)
		return;

	// save basename first
	ar << db_basename;
	ar << db_fname;

	// open db for backup
	sqlite3* save_db = NULL;
	sqlite3_backup* save_bu = NULL;
	opres = sqlite3_open(db_fname.c_str(), &save_db);
	// and prepare backup process
	if(opres == SQLITE_OK)
		save_bu = sqlite3_backup_init(save_db, "main", src_db, "main");
	if(!save_bu) {
		// probably source & dest db are the same
		sqlite3_close(save_db);
		return;
	}

	// copy data to save_db
	while((opres = sqlite3_backup_step(save_bu, -1)) == SQLITE_OK) {}
	sqlite3_backup_finish(save_bu);
	sqlite3_close(save_db);
	// SQLITE_BUSY returned if we're trying to backup into source db
	if(opres != SQLITE_DONE && opres != SQLITE_BUSY) {
		// if error happens - kill db file
		::remove(db_fname.c_str());
	}

	// save flag that db backup was successful and filename of backup db
	//do_write_db = true;
	//ar << do_write_db;
BLUE_SKY_CLASS_SRZ_FCN_END

BLUE_SKY_CLASS_SRZ_FCN_BEGIN(load, blue_sky::sql_well)
	// load filename
	ar >> (std::string&)t.file_name;
	// and flag if we should restore db
	bool do_load_db;
	ar >> do_load_db;
	if(!do_load_db) return;

	// backup db handle
	sqlite3* bu_db;
	int opres;

	// load backup db fname
	std::string db_basename, db_fname;
	ar >> db_basename >> db_fname;

	// check if hdm serializer saved project path for us
	kernel::idx_dt_ptr kdt = BS_KERNEL.pert_idx_dt(BS_KERNEL.find_type("hdm").td_);
	if(kdt && kdt->size< std::string >()) {
		std::string prj_path = kdt->ss< std::string >(0);
		// try to open db relative to project path
		std::string db_relname = prj_path + PATHSEP + db_basename;
		opres = sqlite3_open(db_relname.c_str(), &bu_db);
		if(opres == SQLITE_OK) {
			// save handle to open db
			t.db = bu_db;
			return;
		}
		else
			sqlite3_close(bu_db);
	}

	opres = sqlite3_open(db_fname.c_str(), &bu_db);
	if(opres == SQLITE_OK) {
		// just save handle to db into sql_well and we're done
		t.db = bu_db;
		return;
	}
	// finally try to open db from stored path t.file_name
	sqlite3_close(bu_db);
	opres = sqlite3_open(t.file_name.c_str(), &bu_db);
	if(opres == SQLITE_OK)
		t.db = bu_db;
	else
		sqlite3_close(bu_db);
BLUE_SKY_CLASS_SRZ_FCN_END

// generate serialize() function that uses save & load
//BLUE_SKY_CLASS_SERIALIZE_SPLIT(blue_sky::sql_well)
BLUE_SKY_CLASS_SRZ_FCN_BEGIN(serialize, blue_sky::sql_well)
	// register conversion to base iface
	boser::bs_void_cast_register(
		static_cast< sql_well* >(NULL),
		static_cast< well_pool_iface* >(NULL)
	);
	// split into save/load
	boser::split_free(ar, t, version);
BLUE_SKY_CLASS_SRZ_FCN_END

// instantiate serialization code
BLUE_SKY_TYPE_SERIALIZE_DECL(blue_sky::sql_well)
BLUE_SKY_TYPE_SERIALIZE_IMPL(blue_sky::sql_well)

<|endoftext|>


<commit_before>/// @file sql_well_serialize.cpp
/// @brief Serialization implementations for sql_well
/// @author uentity
/// @version
/// @date 20.01.2012
/// @copyright This source code is released under the terms of
///            the BSD License. See LICENSE for more details.

#include "bs_bos_core_data_storage_stdafx.h"

#include "bs_serialize.h"
#include "bs_misc.h"
#include "sql_well.h"

#include <boost/serialization/string.hpp>

#include <boost/uuid/uuid.hpp>
//#include <boost/uuid/string_generator.hpp>
#include <boost/uuid/random_generator.hpp>
#include <boost/uuid/uuid_io.hpp>
#include <boost/python.hpp>
#include <boost/filesystem/operations.hpp>

#include <stdio.h>

// path separator
#ifdef UNIX
#define PATHSEP '/'
#define PATHSEP_W L'/'
#else
#define PATHSEP '\\'
#define PATHSEP_W L'\\'
#endif

using namespace blue_sky;
namespace bu = boost::uuids;
namespace boser = boost::serialization;

BLUE_SKY_CLASS_SRZ_FCN_BEGIN(save, blue_sky::sql_well)
	// save file_name
	// NOTE: ensure that all filenames are saved in UTF-8 encoding
	ar << (const std::string&)str2ustr(t.file_name);

	// check db has an associated filename
	// strangely there is no such API function though it is documented
	//std::string db_fname(sqlite3_db_filename(t.db, "main"));
	std::string db_fname, prj_path, db_basename;
	// check if hdm serializer saved filename for us
	kernel::idx_dt_ptr kdt = BS_KERNEL.pert_idx_dt(BS_KERNEL.find_type("hdm").td_);
	if(kdt && kdt->size< std::string >() > 1) {
		prj_path = kdt->ss< std::string >(0);
		db_basename = kdt->ss< std::string >(1);
		// if we should make a deep copy of well pool - add given suffix to filename
		if(kdt->size< std::string >() > 2)
			db_basename += std::string("_") + kdt->ss< std::string >(2);
		db_basename += ".db";
		db_fname = prj_path + PATHSEP + db_basename;
	}
	else {
		db_basename = t.file_name;
		db_fname = t.file_name;
	}

	// generate uuid that is part of filename
	if(db_basename.empty()) {
		bu::uuid db_uuid = bu::random_generator()();
		db_basename = bu::to_string(db_uuid) + ".db";
		db_fname = db_basename;
		//db_fname = std::string("file:") + db_basename;
	}

	// flag indicating whether we should backup db
	bool do_write_db = true;
	// check if database is open
	int cur_s, hiwtr, opres = SQLITE_OK + 1;
	sqlite3* src_db = t.db;
	if(src_db)
		opres = sqlite3_db_status(src_db, 0, &cur_s, &hiwtr, 0);
	if(opres != SQLITE_OK) {
		// probably db is closed or not open or whatever
		// try to open it using contained file_name
		// or db_basename
		if(t.file_name.size())
			opres = sqlite3_open_v2(t.file_name.c_str(), &src_db, SQLITE_OPEN_READONLY, NULL);
		if(opres != SQLITE_OK)
			opres = sqlite3_open_v2(db_fname.c_str(), &src_db, SQLITE_OPEN_READONLY, NULL);
		if(opres != SQLITE_OK) {
			sqlite3_close(src_db);
			do_write_db = false;
		}
	}

	ar << do_write_db;
	// if db not open now, we're done
	if(!do_write_db)
		return;

	// save basename first
	ar << (const std::string&)str2ustr(db_basename);
	ar << (const std::string&)str2ustr(db_fname);

	// open db for backup
	sqlite3* save_db = NULL;
	sqlite3_backup* save_bu = NULL;
	opres = sqlite3_open(db_fname.c_str(), &save_db);
	// and prepare backup process
	if(opres == SQLITE_OK)
		save_bu = sqlite3_backup_init(save_db, "main", src_db, "main");
	if(!save_bu) {
		// probably source & dest db are the same
		sqlite3_close(save_db);
		return;
	}

	// copy data to save_db
	while((opres = sqlite3_backup_step(save_bu, -1)) == SQLITE_OK) {}
	sqlite3_backup_finish(save_bu);
	sqlite3_close(save_db);
	// SQLITE_BUSY returned if we're trying to backup into source db
	if(opres != SQLITE_DONE && opres != SQLITE_BUSY) {
		// if error happens - kill saved db file
		::remove(db_fname.c_str());
	}

	// save flag that db backup was successful and filename of backup db
	//do_write_db = true;
	//ar << do_write_db;
BLUE_SKY_CLASS_SRZ_FCN_END

BLUE_SKY_CLASS_SRZ_FCN_BEGIN(load, blue_sky::sql_well)
	// load filename
	// NOTE: Sqlite supports UTF-8 encoded filenames, so no conversion is needed
	// for
	ar >> t.file_name;
	// and flag if we should restore db
	bool do_load_db;
	ar >> do_load_db;
	if(!do_load_db) return;

	// backup db handle
	sqlite3* bu_db;
	int opres;

	// load backup db fname
	std::string db_basename, db_fname;
	ar >> db_basename >> db_fname;

	// check if hdm serializer saved project path for us
	kernel::idx_dt_ptr kdt = BS_KERNEL.pert_idx_dt(BS_KERNEL.find_type("hdm").td_);
	if(kdt && kdt->size< std::string >()) {
		std::string prj_path = kdt->ss< std::string >(0);
		// try to open db relative to project path
		std::string db_relname = prj_path + PATHSEP + db_basename;
		opres = sqlite3_open(db_relname.c_str(), &bu_db);
		if(opres == SQLITE_OK) {
			// save handle to open db
			t.db = bu_db;
			t.file_name = db_relname;
			return;
		}
		sqlite3_close(bu_db);
	}

	opres = sqlite3_open(db_fname.c_str(), &bu_db);
	if(opres == SQLITE_OK) {
		// just save handle to db into sql_well and we're done
		t.db = bu_db;
		t.file_name = db_fname;
		return;
	}
	// finally try to open db from stored path t.file_name
	sqlite3_close(bu_db);
	opres = sqlite3_open(t.file_name.c_str(), &bu_db);
	if(opres == SQLITE_OK)
		t.db = bu_db;
	else {
		// failed to open DB
		sqlite3_close(bu_db);
		t.db = 0;
		t.file_name.clear();
	}
BLUE_SKY_CLASS_SRZ_FCN_END

// generate serialize() function that uses save & load
//BLUE_SKY_CLASS_SERIALIZE_SPLIT(blue_sky::sql_well)
BLUE_SKY_CLASS_SRZ_FCN_BEGIN(serialize, blue_sky::sql_well)
	// register conversion to base iface
	boser::bs_void_cast_register(
		static_cast< sql_well* >(NULL),
		static_cast< well_pool_iface* >(NULL)
	);
	// split into save/load
	boser::split_free(ar, t, version);
BLUE_SKY_CLASS_SRZ_FCN_END

// instantiate serialization code
BLUE_SKY_TYPE_SERIALIZE_DECL(blue_sky::sql_well)
BLUE_SKY_TYPE_SERIALIZE_IMPL(blue_sky::sql_well)

#ifdef BSPY_EXPORTING_PLUGIN
namespace blue_sky { namespace python {

// helper function to write well_pool to given fname
std::string serialize_to_fname(
		smart_ptr< well_pool_iface > wp,
		const std::string& prj_path,
		const std::string& prj_name,
		bool switch_conn = false
	) {
	// save project path for serialization code
	kernel::idx_dt_ptr p_dt = BS_KERNEL.pert_idx_dt(BS_KERNEL.find_type("hdm").td_);
	// save existing contents of kernel table
	ulong sz = p_dt->size< std::string >();
	std::vector< std::string > prev_tbl(sz);
	for(ulong i = 0; i < sz; ++i)
		prev_tbl[i] = p_dt->ss< std::string >(i);

	// clear kernel table to not confuse with further saves
	p_dt->clear< std::string >();

	// decode widestring paths
	//const std::string prj_path_ = wstr2str(prj_path);
	//const std::string prj_name_ = wstr2str(prj_name);
	const std::string db_fname = prj_path + PATHSEP + prj_name + ".db";
	//const std::wstring db_fname = prj_path + PATHSEP_W + prj_name + L".db";

	// insert given data
	p_dt->insert< std::string >(prj_path);
	p_dt->insert< std::string >(prj_name);

	// invoke serializetion
	std::string res = serialize_to_str< well_pool_iface >(wp);
	// switch to newly created DB if requested
	if(switch_conn && boost::filesystem::exists(db_fname)) {
		wp->open_db(db_fname);
	}

	// restore table
	p_dt->clear< std::string >();
	for(ulong i = 0; i < prev_tbl.size(); ++i)
		p_dt->insert< std::string >(prev_tbl[i]);

	return res;
}

BOOST_PYTHON_FUNCTION_OVERLOADS(serialize_to_fname_ol, serialize_to_fname, 3, 4)

BS_API_PLUGIN void py_export_sql_well_serialize() {
	using namespace boost::python;

	std::string (*s2s_wpi)(const smart_ptr< well_pool_iface, true >&) = &blue_sky::serialize_to_str< well_pool_iface >;
	std::string (*s2s_sqw)(const smart_ptr< sql_well, true >&) =
		&blue_sky::serialize_to_str_indirect< sql_well, well_pool_iface >;
	smart_ptr< well_pool_iface, true > (*sfs_wpi)(const std::string&) = &blue_sky::serialize_from_str< well_pool_iface >;
	smart_ptr< sql_well, true > (*sfs_sqw)(const std::string&) =
		&blue_sky::serialize_from_str_indirect< sql_well, well_pool_iface >;

	def("serialize_to_str", s2s_wpi);
	def("serialize_to_str", s2s_sqw);
	def("serialize_from_str", sfs_wpi);
	def("serialize_from_str", sfs_sqw);
	def("serialize_to_fname", &serialize_to_fname, serialize_to_fname_ol());
}

}} /* blue_sky::python */
#endif // #ifdef BSPY_EXPORTING_PLUGIN

<commit_msg>sql_well: fix serialization of filenames (encoding issues)<commit_after>/// @file sql_well_serialize.cpp
/// @brief Serialization implementations for sql_well
/// @author uentity
/// @version
/// @date 20.01.2012
/// @copyright This source code is released under the terms of
///            the BSD License. See LICENSE for more details.

#include "bs_bos_core_data_storage_stdafx.h"

#include "bs_serialize.h"
#include "bs_misc.h"
#include "sql_well.h"

#include <boost/serialization/string.hpp>

#include <boost/uuid/uuid.hpp>
//#include <boost/uuid/string_generator.hpp>
#include <boost/uuid/random_generator.hpp>
#include <boost/uuid/uuid_io.hpp>
#include <boost/python.hpp>
#include <boost/filesystem/operations.hpp>

#include <stdio.h>

// path separator
#ifdef UNIX
#define PATHSEP '/'
#define PATHSEP_W L'/'
#else
#define PATHSEP '\\'
#define PATHSEP_W L'\\'
#endif

using namespace blue_sky;
namespace bu = boost::uuids;
namespace boser = boost::serialization;

BLUE_SKY_CLASS_SRZ_FCN_BEGIN(save, blue_sky::sql_well)
	// save file_name
	// NOTE: ensure that all filenames are saved in UTF-8 encoding
	ar << (const std::string&)str2ustr(t.file_name);

	// check db has an associated filename
	// strangely there is no such API function though it is documented
	//std::string db_fname(sqlite3_db_filename(t.db, "main"));
	std::string db_fname, prj_path, db_basename;
	// check if hdm serializer saved filename for us
	kernel::idx_dt_ptr kdt = BS_KERNEL.pert_idx_dt(BS_KERNEL.find_type("hdm").td_);
	if(kdt && kdt->size< std::string >() > 1) {
		prj_path = kdt->ss< std::string >(0);
		db_basename = kdt->ss< std::string >(1);
		// if we should make a deep copy of well pool - add given suffix to filename
		if(kdt->size< std::string >() > 2)
			db_basename += std::string("_") + kdt->ss< std::string >(2);
		db_basename += ".db";
		db_fname = prj_path + PATHSEP + db_basename;
	}
	else {
		db_basename = t.file_name;
		db_fname = t.file_name;
	}

	// generate uuid that is part of filename
	if(db_basename.empty()) {
		bu::uuid db_uuid = bu::random_generator()();
		db_basename = bu::to_string(db_uuid) + ".db";
		db_fname = db_basename;
		//db_fname = std::string("file:") + db_basename;
	}

	// assume, that paths in kernel table are in native system encoding
	// convert 'em to utf-8 before usage
	db_basename = str2ustr(db_basename);
	db_fname = str2ustr(db_fname);

	// flag indicating whether we should backup db
	bool do_write_db = true;
	// check if database is open
	int cur_s, hiwtr, opres = SQLITE_OK + 1;
	sqlite3* src_db = t.db;
	if(src_db)
		opres = sqlite3_db_status(src_db, 0, &cur_s, &hiwtr, 0);
	if(opres != SQLITE_OK) {
		// probably db is closed or not open or whatever
		// try to open it using contained file_name
		// or db_basename
		if(t.file_name.size())
			opres = sqlite3_open_v2(t.file_name.c_str(), &src_db, SQLITE_OPEN_READONLY, NULL);
		if(opres != SQLITE_OK)
			opres = sqlite3_open_v2(db_fname.c_str(), &src_db, SQLITE_OPEN_READONLY, NULL);
		if(opres != SQLITE_OK) {
			sqlite3_close(src_db);
			do_write_db = false;
		}
	}

	ar << do_write_db;
	// if db not open now, we're done
	if(!do_write_db)
		return;

	// save basename first
	ar << db_basename;
	ar << db_fname;

	// open db for backup
	sqlite3* save_db = NULL;
	sqlite3_backup* save_bu = NULL;
	opres = sqlite3_open(db_fname.c_str(), &save_db);
	// and prepare backup process
	if(opres == SQLITE_OK)
		save_bu = sqlite3_backup_init(save_db, "main", src_db, "main");
	if(!save_bu) {
		// probably source & dest db are the same
		sqlite3_close(save_db);
		return;
	}

	// copy data to save_db
	while((opres = sqlite3_backup_step(save_bu, -1)) == SQLITE_OK) {}
	sqlite3_backup_finish(save_bu);
	sqlite3_close(save_db);
	// SQLITE_BUSY returned if we're trying to backup into source db
	if(opres != SQLITE_DONE && opres != SQLITE_BUSY) {
		// if error happens - kill saved db file
		::remove(ustr2str(db_fname).c_str());
	}

	// save flag that db backup was successful and filename of backup db
	//do_write_db = true;
	//ar << do_write_db;
BLUE_SKY_CLASS_SRZ_FCN_END

BLUE_SKY_CLASS_SRZ_FCN_BEGIN(load, blue_sky::sql_well)
	// load filename
	// NOTE: Sqlite supports UTF-8 encoded filenames, so don't convert anything
	// assume that all file names are saved in UTF-8
	ar >> t.file_name;

	// and flag if we should restore db
	bool do_load_db;
	ar >> do_load_db;
	if(!do_load_db) return;

	// backup db handle
	sqlite3* bu_db;
	int opres;

	// load backup db fname
	std::string db_basename, db_fname;
	ar >> db_basename >> db_fname;

	// check if hdm serializer saved project path for us
	kernel::idx_dt_ptr kdt = BS_KERNEL.pert_idx_dt(BS_KERNEL.find_type("hdm").td_);
	if(kdt && kdt->size< std::string >()) {
		std::string prj_path = str2ustr(kdt->ss< std::string >(0));
		// try to open db relative to project path
		// NOTE: assume that kernel paths are in native system encoding
		std::string db_relname = str2ustr(prj_path + PATHSEP) + db_basename;
		opres = sqlite3_open(db_relname.c_str(), &bu_db);
		if(opres == SQLITE_OK) {
			// save handle to open db
			t.db = bu_db;
			t.file_name = db_relname;
			return;
		}
		sqlite3_close(bu_db);
	}

	opres = sqlite3_open(db_fname.c_str(), &bu_db);
	if(opres == SQLITE_OK) {
		// just save handle to db into sql_well and we're done
		t.db = bu_db;
		t.file_name = db_fname;
		return;
	}
	// finally try to open db from stored path t.file_name
	sqlite3_close(bu_db);
	opres = sqlite3_open(t.file_name.c_str(), &bu_db);
	if(opres == SQLITE_OK)
		t.db = bu_db;
	else {
		// failed to open DB
		sqlite3_close(bu_db);
		t.db = 0;
		t.file_name.clear();
	}
BLUE_SKY_CLASS_SRZ_FCN_END

// generate serialize() function that uses save & load
//BLUE_SKY_CLASS_SERIALIZE_SPLIT(blue_sky::sql_well)
BLUE_SKY_CLASS_SRZ_FCN_BEGIN(serialize, blue_sky::sql_well)
	// register conversion to base iface
	boser::bs_void_cast_register(
		static_cast< sql_well* >(NULL),
		static_cast< well_pool_iface* >(NULL)
	);
	// split into save/load
	boser::split_free(ar, t, version);
BLUE_SKY_CLASS_SRZ_FCN_END

// instantiate serialization code
BLUE_SKY_TYPE_SERIALIZE_DECL(blue_sky::sql_well)
BLUE_SKY_TYPE_SERIALIZE_IMPL(blue_sky::sql_well)

#ifdef BSPY_EXPORTING_PLUGIN
namespace blue_sky { namespace python {

// helper function to write well_pool to given fname
std::string serialize_to_fname(
		smart_ptr< well_pool_iface > wp,
		const std::string& prj_path,
		const std::string& prj_name,
		bool switch_conn = false
	) {
	// save project path for serialization code
	kernel::idx_dt_ptr p_dt = BS_KERNEL.pert_idx_dt(BS_KERNEL.find_type("hdm").td_);
	// save existing contents of kernel table
	ulong sz = p_dt->size< std::string >();
	std::vector< std::string > prev_tbl(sz);
	for(ulong i = 0; i < sz; ++i)
		prev_tbl[i] = p_dt->ss< std::string >(i);

	// clear kernel table to not confuse with further saves
	p_dt->clear< std::string >();

	// decode widestring paths
	//const std::string prj_path_ = wstr2str(prj_path);
	//const std::string prj_name_ = wstr2str(prj_name);
	const std::string db_fname = prj_path + PATHSEP + prj_name + ".db";
	//const std::wstring db_fname = prj_path + PATHSEP_W + prj_name + L".db";

	// insert given data
	p_dt->insert< std::string >(prj_path);
	p_dt->insert< std::string >(prj_name);

	// invoke serializetion
	std::string res = serialize_to_str< well_pool_iface >(wp);
	// switch to newly created DB if requested
	if(switch_conn && boost::filesystem::exists(db_fname)) {
		wp->open_db(db_fname);
	}

	// restore table
	p_dt->clear< std::string >();
	for(ulong i = 0; i < prev_tbl.size(); ++i)
		p_dt->insert< std::string >(prev_tbl[i]);

	return res;
}

BOOST_PYTHON_FUNCTION_OVERLOADS(serialize_to_fname_ol, serialize_to_fname, 3, 4)

BS_API_PLUGIN void py_export_sql_well_serialize() {
	using namespace boost::python;

	std::string (*s2s_wpi)(const smart_ptr< well_pool_iface, true >&) = &blue_sky::serialize_to_str< well_pool_iface >;
	std::string (*s2s_sqw)(const smart_ptr< sql_well, true >&) =
		&blue_sky::serialize_to_str_indirect< sql_well, well_pool_iface >;
	smart_ptr< well_pool_iface, true > (*sfs_wpi)(const std::string&) = &blue_sky::serialize_from_str< well_pool_iface >;
	smart_ptr< sql_well, true > (*sfs_sqw)(const std::string&) =
		&blue_sky::serialize_from_str_indirect< sql_well, well_pool_iface >;

	def("serialize_to_str", s2s_wpi);
	def("serialize_to_str", s2s_sqw);
	def("serialize_from_str", sfs_wpi);
	def("serialize_from_str", sfs_sqw);
	def("serialize_to_fname", &serialize_to_fname, serialize_to_fname_ol());
}

}} /* blue_sky::python */
#endif // #ifdef BSPY_EXPORTING_PLUGIN

<|endoftext|>


<commit_before>
#include "AudioEffectFreqShift_FD_F32.h"

void AudioEffectFreqShift_FD_F32::update(void)
{
	//get a pointer to the latest data
	audio_block_f32_t *in_audio_block = AudioStream_F32::receiveReadOnly_f32();
	if (!in_audio_block) return;

	//simply return the audio if this class hasn't been enabled
	if (!enabled) {
		AudioStream_F32::transmit(in_audio_block);
		AudioStream_F32::release(in_audio_block);
		return;
	}

	//convert to frequency domain
	myFFT.execute(in_audio_block, complex_2N_buffer); //FFT is in complex_2N_buffer, interleaved real, imaginary, real, imaginary, etc
	unsigned long incoming_id = in_audio_block->id;
	AudioStream_F32::release(in_audio_block);  //We just passed ownership of in_audio_block to myFFT, so we can release it here as we won't use it here again.

	// ////////////// Do your processing here!!!

	//define some variables
	int fftSize = myFFT.getNFFT();
	int N_2 = fftSize / 2 + 1;
	int source_ind; // neg_dest_ind;

	//zero out DC and Nyquist
	//complex_2N_buffer[0] = 0.0;  complex_2N_buffer[1] = 0.0;
	//complex_2N_buffer[N_2] = 0.0;  complex_2N_buffer[N_2] = 0.0;

	//do the shifting
	if (shift_bins < 0) {
		for (int dest_ind=0; dest_ind < N_2; dest_ind++) {
		  source_ind = dest_ind - shift_bins;
		  if (source_ind < N_2) {
			complex_2N_buffer[2 * dest_ind] = complex_2N_buffer[2 * source_ind]; //real
			complex_2N_buffer[(2 * dest_ind) + 1] = complex_2N_buffer[(2 * source_ind) + 1]; //imaginary
		  } else {
			complex_2N_buffer[2 * dest_ind] = 0.0;
			complex_2N_buffer[(2 * dest_ind) + 1] = 0.0;
		  }
		}
	} else if (shift_bins > 0) {
		//do reverse order because, otherwise, we'd overwrite our source indices with zeros!
		for (int dest_ind=N_2-1; dest_ind >= 0; dest_ind--) {
			source_ind = dest_ind - shift_bins;
			if (source_ind >= 0) {
				complex_2N_buffer[2 * dest_ind] = complex_2N_buffer[2 * source_ind]; //real
				complex_2N_buffer[(2 * dest_ind) + 1] = complex_2N_buffer[(2 * source_ind) +1]; //imaginary
			} else {
				complex_2N_buffer[2 * dest_ind] = 0.0;
				complex_2N_buffer[(2 * dest_ind) + 1] = 0.0;
			}
		}
	}

	//here's the tricky bit!  Phase shifting may be needed through time
	switch (overlap_amount) {
		case NONE:
			//no phase change needed
			break;
		case HALF:
			//we only need to adjust the phase if we're shifting by an odd number of bins
			if ((abs(shift_bins) % 2) == 1) {
				//Alternate between adding no phase shift and adding 180 deg phase shift.
				//Adding 180 is the same as flipping the sign of both the real and imaginary components
				overlap_block_counter++;
				if (overlap_block_counter == 2){
					overlap_block_counter = 0;
					for (int i=0; i < N_2; i++) {
						complex_2N_buffer[2*i] = -complex_2N_buffer[2*i];
						complex_2N_buffer[2*i+1] = -complex_2N_buffer[2*i+1];
					}
				}
			}
			break;
		case THREE_QUARTERS:
			//The cycle of phase shifting is every 4 blocks insead of every two blocks.
			overlap_block_counter++; //will be 1 to 4
			if (overlap_block_counter == 4) overlap_block_counter = 0;
			if ((abs(shift_bins) % 2) == 1) { //THIS ISN'T RIGHT ?!?!?  Needs to be fancier, "% 4" instead of "% 2" ???
				float foo;
				switch (overlap_block_counter) {
					case 0:
						//no rotation
						break;
					case 1:
						//90 deg rotation (swap real and imaginary and flip the sign when moving the real to imaginary)
						for (int i=0; i < N_2; i++) {
							foo = complex_2N_buffer[2*i+1];
							complex_2N_buffer[2*i+1] = complex_2N_buffer[2*i];
							complex_2N_buffer[2*i] = -foo;
						}
						break;
					case 2:
						//180 deg...flip the sign of both real and imaginary
						for (int i=0; i < N_2; i++) {
							complex_2N_buffer[2*i] = -complex_2N_buffer[2*i];
							complex_2N_buffer[2*i+1] = -complex_2N_buffer[2*i+1];
						}
						break;
					case 3:
						//270 deg rotation (swap the real and imaginary and flip the sign when moving the imaginary to the real)
						for (int i=0; i < N_2; i++) {
							foo = complex_2N_buffer[2*i+1];
							complex_2N_buffer[2*i+1] = -complex_2N_buffer[2*i];
							complex_2N_buffer[2*i] = foo;
						}
						overlap_block_counter = 0;
						break;
				}
			}
			break;
	}

	//zero out the new DC and new nyquist
	//complex_2N_buffer[0] = 0.0;  complex_2N_buffer[1] = 0.0;
	//complex_2N_buffer[N_2] = 0.0;  complex_2N_buffer[N_2] = 0.0;

	//rebuild the negative frequency space
	myFFT.rebuildNegativeFrequencySpace(complex_2N_buffer); //set the negative frequency space based on the positive

	// ///////////// End do your processing here

	//call the IFFT
	audio_block_f32_t *out_audio_block = myIFFT.execute(complex_2N_buffer); //out_block is pre-allocated in here.

	//update the block number to match the incoming one
	out_audio_block->id = incoming_id;

	//send the returned audio block.  Don't issue the release command here because myIFFT will re-use it
	AudioStream_F32::transmit(out_audio_block); //don't release this buffer because myIFFT re-uses it within its own code
	return;
};<commit_msg>AudioEffectFreqShift_FD_F32: fix phase corrections for 75% overlap<commit_after>
#include "AudioEffectFreqShift_FD_F32.h"

void AudioEffectFreqShift_FD_F32::update(void)
{
	//get a pointer to the latest data
	audio_block_f32_t *in_audio_block = AudioStream_F32::receiveReadOnly_f32();
	if (!in_audio_block) return;

	//simply return the audio if this class hasn't been enabled
	if (!enabled) {
		AudioStream_F32::transmit(in_audio_block);
		AudioStream_F32::release(in_audio_block);
		return;
	}

	//convert to frequency domain
	myFFT.execute(in_audio_block, complex_2N_buffer); //FFT is in complex_2N_buffer, interleaved real, imaginary, real, imaginary, etc
	unsigned long incoming_id = in_audio_block->id;
	AudioStream_F32::release(in_audio_block);  //We just passed ownership of in_audio_block to myFFT, so we can release it here as we won't use it here again.

	// ////////////// Do your processing here!!!

	//define some variables
	int fftSize = myFFT.getNFFT();
	int N_2 = fftSize / 2 + 1;
	int source_ind; // neg_dest_ind;

	//zero out DC and Nyquist
	//complex_2N_buffer[0] = 0.0;  complex_2N_buffer[1] = 0.0;
	//complex_2N_buffer[N_2] = 0.0;  complex_2N_buffer[N_2] = 0.0;

	//do the shifting
	if (shift_bins < 0) {
		for (int dest_ind=0; dest_ind < N_2; dest_ind++) {
		  source_ind = dest_ind - shift_bins;
		  if (source_ind < N_2) {
			complex_2N_buffer[2 * dest_ind] = complex_2N_buffer[2 * source_ind]; //real
			complex_2N_buffer[(2 * dest_ind) + 1] = complex_2N_buffer[(2 * source_ind) + 1]; //imaginary
		  } else {
			complex_2N_buffer[2 * dest_ind] = 0.0;
			complex_2N_buffer[(2 * dest_ind) + 1] = 0.0;
		  }
		}
	} else if (shift_bins > 0) {
		//do reverse order because, otherwise, we'd overwrite our source indices with zeros!
		for (int dest_ind=N_2-1; dest_ind >= 0; dest_ind--) {
			source_ind = dest_ind - shift_bins;
			if (source_ind >= 0) {
				complex_2N_buffer[2 * dest_ind] = complex_2N_buffer[2 * source_ind]; //real
				complex_2N_buffer[(2 * dest_ind) + 1] = complex_2N_buffer[(2 * source_ind) +1]; //imaginary
			} else {
				complex_2N_buffer[2 * dest_ind] = 0.0;
				complex_2N_buffer[(2 * dest_ind) + 1] = 0.0;
			}
		}
	}

	//here's the tricky bit!  Phase shifting may be needed through time
	switch (overlap_amount) {
		case NONE:
			//no phase change needed
			break;

		case HALF:
			//we only need to adjust the phase if we're shifting by an odd number of bins
			if ((abs(shift_bins) % 2) == 1) {
				//Alternate between adding no phase shift and adding 180 deg phase shift.
				//Adding 180 is the same as flipping the sign of both the real and imaginary components
				overlap_block_counter++;
				if (overlap_block_counter == 2){
					overlap_block_counter = 0;
					for (int i=0; i < N_2; i++) {
						complex_2N_buffer[2*i] = -complex_2N_buffer[2*i];
						complex_2N_buffer[2*i+1] = -complex_2N_buffer[2*i+1];
					}
				}
			}
			break;

		case THREE_QUARTERS:
			//The cycle of phase shifting is every 4 blocks insead of every two blocks.
			//Phase_shift = Phase_orig - Phase_new
			//  phase_orig = (360/4) * F_orig * block_counter;  //F_orig = 0 -> Nfft/2+1
			//  phase_new  = (360/4) * F_new * block_counter;
			//  So, phase_shift = (360/4) * (F_new - F_orig) * block_counter;  //wrap this zero to 360
			//  Or, rewritten: phase_shift_deg = (360/4) * -shift_bins * block_counter //wrap this zero to 360
			//  Or, rewritten again: phase_shift_quarters = wrap(-shift_bins * block_counter, 4); //wrapped to always be [0, 1, 2, 3]
			overlap_block_counter++; if (overlap_block_counter >= 4) overlap_block_counter = 0; //will be [0, 1, 2, 3]
			int phase_shift_quarters = shift_bins * overlap_block_counter;
			while (phase_shift_quarters < 0) phase_shift_quarters += 4;  //wrap to get to zero or above
			while (phase_shift_quarters >= 4) phase_shift_quarters -= 4; //wrap get to less than 4

			float foo;
			switch (phase_shift_quarters) {
				case 0:
					//no rotation
					break;
				case 1:
					//90 deg rotation (swap real and imaginary and flip the sign when moving the real to imaginary)
					for (int i=0; i < N_2; i++) {
						foo = complex_2N_buffer[2*i+1];
						complex_2N_buffer[2*i+1] = complex_2N_buffer[2*i];
						complex_2N_buffer[2*i] = -foo;
					}
					break;
				case 2:
					//180 deg...flip the sign of both real and imaginary
					for (int i=0; i < N_2; i++) {
						complex_2N_buffer[2*i] = -complex_2N_buffer[2*i];
						complex_2N_buffer[2*i+1] = -complex_2N_buffer[2*i+1];
					}
					break;
				case 3:
					//270 deg rotation (swap the real and imaginary and flip the sign when moving the imaginary to the real)
					for (int i=0; i < N_2; i++) {
						foo = complex_2N_buffer[2*i+1];
						complex_2N_buffer[2*i+1] = -complex_2N_buffer[2*i];
						complex_2N_buffer[2*i] = foo;
					}
					break;
			}
			break;

	}

	//zero out the new DC and new nyquist
	//complex_2N_buffer[0] = 0.0;  complex_2N_buffer[1] = 0.0;
	//complex_2N_buffer[N_2] = 0.0;  complex_2N_buffer[N_2] = 0.0;

	//rebuild the negative frequency space
	myFFT.rebuildNegativeFrequencySpace(complex_2N_buffer); //set the negative frequency space based on the positive

	// ///////////// End do your processing here

	//call the IFFT
	audio_block_f32_t *out_audio_block = myIFFT.execute(complex_2N_buffer); //out_block is pre-allocated in here.

	//update the block number to match the incoming one
	out_audio_block->id = incoming_id;

	//send the returned audio block.  Don't issue the release command here because myIFFT will re-use it
	AudioStream_F32::transmit(out_audio_block); //don't release this buffer because myIFFT re-uses it within its own code
	return;
};<|endoftext|>