<commit_before>/**
   @file alsadaptor-ascii.cpp
   @brief ALSAdaptor that reads lux value from ascii interface

   Copyright (C) 2009-2010 Intel Corporation
   Copyright (C) 2009-2010 Nokia Corporation

   @author Leo Yan <leo.yan@intel.com>
   @author Timo Rongas <ext-timo.2.rongas@nokia.com>
   @author Ustun Ergenoglu <ext-ustun.ergenoglu@nokia.com>
   @author Matias Muhonen <ext-matias.muhonen@nokia.com>
   @author Tapio Rantala <ext-tapio.rantala@nokia.com>
   @author Antti Virtanen <antti.i.virtanen@nokia.com>
   @author Lihan Guo <ext-lihan.4.guo@nokia.com>

   This file is part of Sensord.

   Sensord is free software; you can redistribute it and/or modify
   it under the terms of the GNU Lesser General Public License
   version 2.1 as published by the Free Software Foundation.

   Sensord is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with Sensord.  If not, see <http://www.gnu.org/licenses/>.

*/

#include <fcntl.h>
#include <sys/stat.h>
#include <errno.h>
#include <QFile>

#include "logging.h"
#include "config.h"
#include "alsadaptor-ascii.h"
#include "datatypes/utils.h"
#include <stdlib.h>
#include <linux/types.h>
#include <string.h>

ALSAdaptorAscii::ALSAdaptorAscii(const QString& id) : SysfsAdaptor(id, SysfsAdaptor::IntervalMode)
{
    memset(buf, 0x0, 16);
    alsBuffer_ = new DeviceAdaptorRingBuffer<TimedUnsigned>(1);
    setAdaptedSensor("als", "Internal ambient light sensor lux values", alsBuffer_);
    setDescription("Ambient light");
}

ALSAdaptorAscii::~ALSAdaptorAscii()
{
    delete alsBuffer_;
}

void ALSAdaptorAscii::processSample(int pathId, int fd) {
    Q_UNUSED(pathId);

    if (read(fd, buf, sizeof(buf)) <= 0) {
        sensordLogW() << "read():" << strerror(errno);
        return;
    }
    buf[sizeof(buf)-1] = '\0';

    sensordLogT() << "Ambient light value: " << buf;

    __u16 idata = atoi(buf);

    TimedUnsigned* lux = alsBuffer_->nextSlot();

    lux->value_ = idata;
    lux->timestamp_ = Utils::getTimeStamp();

    alsBuffer_->commit();
    alsBuffer_->wakeUpReaders();
}
<commit_msg>add sensorfw-0.7.1-alsadaptor-ascii-rangefile.patch<commit_after>/**
   @file alsadaptor-ascii.cpp
   @brief ALSAdaptor that reads lux value from ascii interface

   Copyright (C) 2009-2010 Intel Corporation
   Copyright (C) 2009-2010 Nokia Corporation

   @author Leo Yan <leo.yan@intel.com>
   @author Timo Rongas <ext-timo.2.rongas@nokia.com>
   @author Ustun Ergenoglu <ext-ustun.ergenoglu@nokia.com>
   @author Matias Muhonen <ext-matias.muhonen@nokia.com>
   @author Tapio Rantala <ext-tapio.rantala@nokia.com>
   @author Antti Virtanen <antti.i.virtanen@nokia.com>
   @author Lihan Guo <ext-lihan.4.guo@nokia.com>

   This file is part of Sensord.

   Sensord is free software; you can redistribute it and/or modify
   it under the terms of the GNU Lesser General Public License
   version 2.1 as published by the Free Software Foundation.

   Sensord is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with Sensord.  If not, see <http://www.gnu.org/licenses/>.

*/

#include <fcntl.h>
#include <sys/stat.h>
#include <errno.h>
#include <QFile>

#include "logging.h"
#include "config.h"
#include "alsadaptor-ascii.h"
#include "datatypes/utils.h"
#include <stdlib.h>
#include <linux/types.h>
#include <string.h>

ALSAdaptorAscii::ALSAdaptorAscii(const QString& id) : SysfsAdaptor(id, SysfsAdaptor::IntervalMode)
{
    memset(buf, 0x0, 16);
    alsBuffer_ = new DeviceAdaptorRingBuffer<TimedUnsigned>(1);
    setAdaptedSensor("als", "Internal ambient light sensor lux values", alsBuffer_);
    setDescription("Ambient light");

    // Get range from a file, if the path is found in configuration
    QString rangeFilePath_ = Config::configuration()->value("als/range_file_path",QVariant("")).toString();
    if (rangeFilePath_ != "") {
        QFile sysFile(rangeFilePath_);

        if (!(sysFile.open(QIODevice::ReadOnly))) {
            sensordLogW() << "Unable to config ALS range from sysfs";
        } else {
            sysFile.readLine(buf, sizeof(buf));
            int range = QString(buf).toInt();

            introduceAvailableDataRange(DataRange(0, range, 1));
            sensordLogT() << "Ambient light range: " << range;
        }
    }
}

ALSAdaptorAscii::~ALSAdaptorAscii()
{
    delete alsBuffer_;
}

void ALSAdaptorAscii::processSample(int pathId, int fd) {
    Q_UNUSED(pathId);

    if (read(fd, buf, sizeof(buf)) <= 0) {
        sensordLogW() << "read():" << strerror(errno);
        return;
    }
    buf[sizeof(buf)-1] = '\0';

    sensordLogT() << "Ambient light value: " << buf;

    __u16 idata = atoi(buf);

    TimedUnsigned* lux = alsBuffer_->nextSlot();

    lux->value_ = idata;
    lux->timestamp_ = Utils::getTimeStamp();

    alsBuffer_->commit();
    alsBuffer_->wakeUpReaders();
}
<|endoftext|>


<commit_before>#include "skin-detect.h"

int main(int argc, char** argv)
{
	if (argc != 2)   //Check the correct syntax is used to open a file
	{
		cout << "Usage: " << argv[0] << " Video" << endl;
		return -1;
	}
	VideoCapture cap(argv[1]); //Open Video
	if (!cap.isOpened())   //Check if video has been opened correctly
	{
		cout << "Cannot open camera" << endl;
		return -1;
	}
	//for (int i=0; i<3000; i++) { //Skip to interesting parts of long videos
	cap >> img; //Capture the first frame of the video
	//}
	if (!img.data)  //Check for invalid input
	{
		cout <<  "Could not open video" << endl ;
		return -1;
	}
	cvtColor(img, imgFilter, CV_BGR2YCrCb); //Convert to YUV colorspace
	namedWindow(window1_name, CV_WINDOW_AUTOSIZE);  //Create video window
	namedWindow(window2_name, CV_WINDOW_AUTOSIZE);  //Create thresholded video window
	while (true)
	{
		c = waitKey(20);
		if ((char)c == 27) break; //Exit if ESC key is hit
		//Debug info
		cout << "Frames in video: " << cap.get(CV_CAP_PROP_FRAME_COUNT) << "	Current Frame: " << cap.get(CV_CAP_PROP_POS_FRAMES) << "	FPS: " << cap.get(CV_CAP_PROP_FPS) << endl;
		if (cap.get(CV_CAP_PROP_FRAME_COUNT) > cap.get(CV_CAP_PROP_POS_FRAMES))   //If current frame is less than length of video
		{
			imshow(window1_name, img); //Show captured frame
			colour_segmentation();
			density_regularisation();
			luminance_regularisation();
			geometric_correction();
			imshow(window2_name, imgFilter);
			cap >> img; //Capture next frame
			cvtColor(img, imgFilter, CV_BGR2YCrCb); //Convert to YUV colourspace
		}
		else cap.set(CV_CAP_PROP_POS_FRAMES, 0); //If EOF go to start (and collect £200)
	}
}

/***********************************************************************
 * Step 1: Colour Segmentation
 *
 * Classify pixels as either skin or non-skin. Skin tones fall within a
 * small range of Chrominance values:
 * Cr = 133 to 173
 * Cb = 77 to 127
 **********************************************************************/

void colour_segmentation()
{
	inRange(img, Scalar(0, 77, 133), Scalar(255, 127, 173), imgFilter);
}

/***********************************************************************
 * Step 2: Density Regularisation
 *
 * Colour segmentation produces a very noisy image with a lot of false
 * positives. We therefore need to find areas with a high probability of
 * that belong to the facial region. Group pixels in 4x4 clusters and
 * find the sum of skin coloured pixels in each cluster.
 *
 * Classify each cluster as follows to achieve a density map:
 * 0 <= sum < 16; noise or non-facial region
 * sum = 16; facial region
 *
 * Following this perform morphology as below:
 * 1. discard all clusters at the perimeter of the frame
 * 2. Erode any full-density point if it is surrounded by less than ﬁve
 * 	  other full-density points in its local 3x3 neighborhood
 * 3. Dilate any point of either zero or intermediate density if there
 *    are more than two full-density points in its local 3x3
 *    neighborhood
 **********************************************************************/
void density_regularisation()
{
	Mat sum;
	sum = Mat::zeros(img.rows, img.cols, CV_8UC1);
	uchar op;
	int erode, dilate;
	for (int i = 0; i < img.rows; i+=4) //Cycle over horizontal clusters
	{
		for (int j = 0; j < img.cols; j+=4) //Cycle over vertical clusters
		{
			for (int k = 0; k < 4; k++) //Cycle horizontally within cluster
			{
				for (int l = 0; l < 4; l++) //Cycle vertically within cluster
				{
					if (imgFilter.at<uchar>(i + k, j + l) != 0) sum.at<uchar>(i, j)++;
				}
			}
			if (sum.at<uchar>(i, j) == 0 || i == 0 || j == 0 || i == (img.rows - 4) / 4 || j == (img.cols - 4) / 4) op = 0;
			else if (sum.at<uchar>(i, j) > 0 &&  sum.at<uchar>(i, j) < 16) op = 128;
			else op = 255;
			for (int k = 0; k < 4; k++) //Cycle horizontally within cluster
			{
				for (int l = 0; l < 4; l++) //Cycle vertically within cluster
				{
					imgFilter.at<uchar>(i + k, j + l) = op;
				}
			}
		}
	}
	for (int i = 0; i < img.rows; i+=4) //Cycle over horizontal clusters
	{
		for (int j = 0; j < img.cols; j+=4) //Cycle over vertical clusters
		{
			erode = 0;
			if (imgFilter.at<uchar>(i, j) == 255)
			{
				for (int k = -4; k < 5; k += 4)
				{
					for (int l = -4; l < 5; l += 4)
					{
						if (imgFilter.at<uchar>(i + k, j + l) == 255) erode++;
					}
				}
				if (erode < ERODE_SIZE)
				{
					for (int k = 0; k < 4; k++) //Cycle horizontally within cluster
					{
						for (int l = 0; l < 4; l++) //Cycle vertically within cluster
						{
							imgFilter.at<uchar>(i + k, j + l) = 0;
						}
					}
				}
			}
		}
	}
	for (int i = 0; i < img.rows; i+=4) //Cycle over horizontal clusters
	{
		for (int j = 0; j < img.cols; j+=4) //Cycle over vertical clusters
		{
			dilate = 0;
			if (imgFilter.at<uchar>(i, j) < 255)
			{
				for (int k = -4; k < 5; k += 4)
				{
					for (int l = -4; l < 5; l += 4)
					{
						if (imgFilter.at<uchar>(i + k, j + l) == 255) dilate++;
					}
				}
				if (dilate > DILATE_SIZE)
				{
					for (int k = 0; k < 4; k++) //Cycle horizontally within cluster
					{
						for (int l = 0; l < 4; l++) //Cycle vertically within cluster
						{
							imgFilter.at<uchar>(i + k, j + l) = 255;
						}
					}
				}
			}
			for (int k = 0; k < 4; k++) //Cycle horizontally within cluster
			{
				for (int l = 0; l < 4; l++) //Cycle vertically within cluster
				{
					if (imgFilter.at<uchar>(i + k, j + l) != 255) imgFilter.at<uchar>(i + k, j + l) = 0;
				}
			}
		}
	}
}

/***********************************************************************
 * Step 3: Luminance Regularisation
 *
 * In a typical teleconference the brightness is nonuniform throughout
 * the facial region, while the background region tends to have a more
 * even distribution of brightness. Hence, based on this characteristic,
 * background region that was previously detected due to its skin-color
 * appearance can be further eliminated
 *
 * Calculate the standard deviation of the luminance in an 8x8 pixel
 * area (under 4:2:0 subsampling).
 * if (stddev >= 2 && step2value == 1) step3value =1;
 **********************************************************************/

void luminance_regularisation()
{
	float xbar, sse, stddev;
	for (int i = 0; i < img.rows; i+=4) //Cycle over horizontal clusters
	{
		for (int j = 0; j < img.cols; j+=4) //Cycle over vertical clusters
		{
			xbar = 0;
			sse = 0;
			stddev = 0;
			for (int k = 0; k < 4; k++) //Cycle horizontally within cluster
			{
				for (int l = 0; l < 4; l++) //Cycle vertically within cluster
				{
					xbar += img.at<Vec3b>(i + k, j + l)[0];
				}
			}
			xbar /= 16;
			for (int k = 0; k < 4; k++) //Cycle horizontally within cluster
			{
				for (int l = 0; l < 4; l++) //Cycle vertically within cluster
				{
					sse += pow(img.at<Vec3b>(i + k, j + l)[0] - xbar, 2);
				}
			}
			stddev = pow(sse / 16, 0.5);
			for (int k = 0; k < 4; k++) //Cycle horizontally within cluster
			{
				for (int l = 0; l < 4; l++) //Cycle vertically within cluster
				{
					if (imgFilter.at<uchar>(i + k, j + l) == 255 && stddev >= 2) imgFilter.at<uchar>(i + k, j + l) = 255;
				}
			}
		}
	}
}

/***********************************************************************
 * Step Four: Geometric Correction
 *
 * Further mophology:
 * 1. Pixel clusters with value 1 will remain one if surrounded by at
 *    least four clusters of value 1 in its local 3x3 neighborhood
 * 2. Pixel clusters with value 0 will be given value 1 if surrounded
 *    by at least 6 clusters of value 1 in its local 3x3 neighborhood
 *
 * Filter horizontally then vertically setting any runs of less than
 * four clusters to zero
 ***************************************************£******************/

void geometric_correction()
{
	int erode, dilate, sum;
	for (int i = 3; i < (img.rows - 4); i++) //Cycle over horizontal clusters
	{
		for (int j = 3; j < (img.cols - 4); j++) //Cycle over vertical clusters
		{
			erode = 0;
			if (imgFilter.at<uchar>(i, j) == 255)
			{
				for (int k = -4; k < 5; k += 4)
				{
					for (int l = -4; l < 5; l += 4)
					{
						if (imgFilter.at<uchar>(i + k, j + l) == 255) erode++;
					}
				}
				if (erode < DILATE_SIZE)
				{
					for (int k = 0; k < 4; k++) //Cycle horizontally within cluster
					{
						for (int l = 0; l < 4; l++) //Cycle vertically within cluster
						{
							imgFilter.at<uchar>(i + k, j + l) = 0;
						}
					}
				}
			}
		}
	}
	for (int i = 3; i < (img.rows - 4); i++) //Cycle over horizontal clusters
	{
		for (int j = 3; j < (img.cols - 4); j++) //Cycle over vertical clusters
		{
			dilate = 0;
			if (imgFilter.at<uchar>(i, j) < 255)
			{
				for (int k = -4; k < 5; k += 4)
				{
					for (int l = -4; l < 5; l += 4)
					{
						if (imgFilter.at<uchar>(i + k, j + l) == 255) dilate++;
					}
				}
				if (dilate > ERODE_SIZE)
				{
					for (int k = 0; k < 4; k++) //Cycle horizontally within cluster
					{
						for (int l = 0; l < 4; l++) //Cycle vertically within cluster
						{
							imgFilter.at<uchar>(i + k, j + l) = 255;
						}
					}
				}
			}
		}
	}
	for (int i = 3; i < (img.cols - 4); i++) //Cycle over vertical clusters
	{
		for (int j = 3; j < (img.rows - 4); j++) //Cycle over horizontal clusters
		{
			if (imgFilter.at<uchar>(j, i) == 255) sum++;
			else if (sum > 0 && sum < 4 && j < 12)
			{
				for (sum; sum == 0; sum--)
				{
					imgFilter.at<uchar>(j, i - sum) = 0;
				}
			}
		}
	}
	for (int i = 3; i < (img.rows - 4); i++) //Cycle over horizontal clusters
	{
		for (int j = 3; j < (img.cols - 4); j++) //Cycle over vertical clusters
		{
			if (imgFilter.at<uchar>(j, i) == 255) sum++;
			else if (sum > 0 && sum < 4 && j < 12)
			{
				for (sum; sum == 0; sum--)
				{
					imgFilter.at<uchar>(j, i - sum) = 0;
				}
			}
		}
	}
}
<commit_msg>Update skin-detect.cpp<commit_after>#include "skin-detect.h"

int main(int argc, char** argv)
{
	if (argc != 2)   //Check the correct syntax is used to open a file
	{
		cout << "Usage: " << argv[0] << " Video" << endl;
		return -1;
	}
	VideoCapture cap(argv[1]); //Open Video
	if (!cap.isOpened())   //Check if video has been opened correctly
	{
		cout << "Cannot open camera" << endl;
		return -1;
	}
	//for (int i=0; i<3000; i++) { //Skip to interesting parts of long videos
	cap >> img; //Capture the first frame of the video
	//}
	if (!img.data)  //Check for invalid input
	{
		cout <<  "Could not open video" << endl ;
		return -1;
	}
	cvtColor(img, imgFilter, CV_BGR2YCrCb); //Convert to YUV colorspace
	namedWindow(window1_name, CV_WINDOW_AUTOSIZE);  //Create video window
	namedWindow(window2_name, CV_WINDOW_AUTOSIZE);  //Create thresholded video window
	while (true)
	{
		c = waitKey(20);
		if ((char)c == 27) break; //Exit if ESC key is hit
		//Debug info
		cout << "Frames in video: " << cap.get(CV_CAP_PROP_FRAME_COUNT) << "	Current Frame: " << cap.get(CV_CAP_PROP_POS_FRAMES) << "	FPS: " << cap.get(CV_CAP_PROP_FPS) << endl;
		if (cap.get(CV_CAP_PROP_FRAME_COUNT) > cap.get(CV_CAP_PROP_POS_FRAMES))   //If current frame is less than length of video
		{
			imshow(window1_name, img); //Show captured frame
			colour_segmentation();
			density_regularisation();
			luminance_regularisation();
			geometric_correction();
			imshow(window2_name, imgFilter);
			cap >> img; //Capture next frame
			cvtColor(img, imgFilter, CV_BGR2YCrCb); //Convert to YUV colourspace
		}
		else cap.set(CV_CAP_PROP_POS_FRAMES, 0); //If EOF go to start (and collect £200)
	}
}

/***********************************************************************
 * Step 1: Colour Segmentation
 *
 * Classify pixels as either skin or non-skin. Skin tones fall within a
 * small range of Chrominance values:
 * Cr = 133 to 173
 * Cb = 77 to 127
 **********************************************************************/

void colour_segmentation()
{
	inRange(img, Scalar(0, 77, 133), Scalar(255, 127, 173), imgFilter);
}

/***********************************************************************
 * Step 2: Density Regularisation
 *
 * Colour segmentation produces a very noisy image with a lot of false
 * positives. We therefore need to find areas with a high probability of
 * that belong to the facial region. Group pixels in 4x4 clusters and
 * find the sum of skin coloured pixels in each cluster.
 *
 * Classify each cluster as follows to achieve a density map:
 * 0 <= sum < 16; noise or non-facial region
 * sum = 16; facial region
 *
 * Following this perform morphology as below:
 * 1. discard all clusters at the perimeter of the frame
 * 2. Erode any full-density point if it is surrounded by less than ﬁve
 * 	  other full-density points in its local 3x3 neighborhood
 * 3. Dilate any point of either zero or intermediate density if there
 *    are more than two full-density points in its local 3x3
 *    neighborhood
 **********************************************************************/
void density_regularisation()
{
	Mat sum;
	sum = Mat::zeros(img.rows, img.cols, CV_8UC1);
	uchar op;
	int erode, dilate;
	for (int i = 0; i < img.rows; i+=4) //Cycle over horizontal clusters
	{
		for (int j = 0; j < img.cols; j+=4) //Cycle over vertical clusters
		{
			for (int k = 0; k < 4; k++) //Cycle horizontally within cluster
			{
				for (int l = 0; l < 4; l++) //Cycle vertically within cluster
				{
					if (imgFilter.at<uchar>(i + k, j + l) != 0) sum.at<uchar>(i, j)++;
				}
			}
			if (sum.at<uchar>(i, j) == 0 || i == 0 || j == 0 || i == (img.rows - 4) / 4 || j == (img.cols - 4) / 4) op = 0;
			else if (sum.at<uchar>(i, j) > 0 &&  sum.at<uchar>(i, j) < 16) op = 128;
			else op = 255;
			for (int k = 0; k < 4; k++) //Cycle horizontally within cluster
			{
				for (int l = 0; l < 4; l++) //Cycle vertically within cluster
				{
					imgFilter.at<uchar>(i + k, j + l) = op;
				}
			}
		}
	}
	for (int i = 0; i < img.rows; i+=4) //Cycle over horizontal clusters
	{
		for (int j = 0; j < img.cols; j+=4) //Cycle over vertical clusters
		{
			erode = 0;
			if (imgFilter.at<uchar>(i, j) == 255)
			{
				for (int k = -4; k < 5; k += 4)
				{
					for (int l = -4; l < 5; l += 4)
					{
						if (imgFilter.at<uchar>(i + k, j + l) == 255) erode++;
					}
				}
				if (erode < ERODE_SIZE)
				{
					for (int k = 0; k < 4; k++) //Cycle horizontally within cluster
					{
						for (int l = 0; l < 4; l++) //Cycle vertically within cluster
						{
							imgFilter.at<uchar>(i + k, j + l) = 0;
						}
					}
				}
			}
		}
	}
	for (int i = 0; i < img.rows; i+=4) //Cycle over horizontal clusters
	{
		for (int j = 0; j < img.cols; j+=4) //Cycle over vertical clusters
		{
			dilate = 0;
			if (imgFilter.at<uchar>(i, j) < 255)
			{
				for (int k = -4; k < 5; k += 4)
				{
					for (int l = -4; l < 5; l += 4)
					{
						if (imgFilter.at<uchar>(i + k, j + l) == 255) dilate++;
					}
				}
				if (dilate > DILATE_SIZE)
				{
					for (int k = 0; k < 4; k++) //Cycle horizontally within cluster
					{
						for (int l = 0; l < 4; l++) //Cycle vertically within cluster
						{
							imgFilter.at<uchar>(i + k, j + l) = 255;
						}
					}
				}
			}
			for (int k = 0; k < 4; k++) //Cycle horizontally within cluster
			{
				for (int l = 0; l < 4; l++) //Cycle vertically within cluster
				{
					if (imgFilter.at<uchar>(i + k, j + l) != 255) imgFilter.at<uchar>(i + k, j + l) = 0;
				}
			}
		}
	}
}

/***********************************************************************
 * Step 3: Luminance Regularisation
 *
 * In a typical teleconference the brightness is nonuniform throughout
 * the facial region, while the background region tends to have a more
 * even distribution of brightness. Hence, based on this characteristic,
 * background region that was previously detected due to its skin-color
 * appearance can be further eliminated
 *
 * Calculate the standard deviation of the luminance in an 8x8 pixel
 * area (under 4:2:0 subsampling).
 * if (stddev >= 2 && step2value == 1) step3value =1;
 **********************************************************************/

void luminance_regularisation()
{
	float xbar, sse, stddev;
	for (int i = 0; i < img.rows; i+=4) //Cycle over horizontal clusters
	{
		for (int j = 0; j < img.cols; j+=4) //Cycle over vertical clusters
		{
			xbar = 0;
			sse = 0;
			stddev = 0;
			for (int k = 0; k < 4; k++) //Cycle horizontally within cluster
			{
				for (int l = 0; l < 4; l++) //Cycle vertically within cluster
				{
					xbar += img.at<Vec3b>(i + k, j + l)[0];
				}
			}
			xbar /= 16;
			for (int k = 0; k < 4; k++) //Cycle horizontally within cluster
			{
				for (int l = 0; l < 4; l++) //Cycle vertically within cluster
				{
					sse += pow(img.at<Vec3b>(i + k, j + l)[0] - xbar, 2);
				}
			}
			stddev = pow(sse / 16, 0.5);
			for (int k = 0; k < 4; k++) //Cycle horizontally within cluster
			{
				for (int l = 0; l < 4; l++) //Cycle vertically within cluster
				{
					if (imgFilter.at<uchar>(i + k, j + l) == 255 && stddev >= 2) imgFilter.at<uchar>(i + k, j + l) = 255;
				}
			}
		}
	}
}

/***********************************************************************
 * Step Four: Geometric Correction
 *
 * Further mophology:
 * 1. Pixel clusters with value 1 will remain one if surrounded by at
 *    least four clusters of value 1 in its local 3x3 neighborhood
 * 2. Pixel clusters with value 0 will be given value 1 if surrounded
 *    by at least 6 clusters of value 1 in its local 3x3 neighborhood
 *
 * Filter horizontally then vertically setting any runs of less than
 * four clusters to zero
 **********************************************************************/

void geometric_correction()
{
	int erode, dilate, sum;
	for (int i = 3; i < (img.rows - 4); i++) //Cycle over horizontal clusters
	{
		for (int j = 3; j < (img.cols - 4); j++) //Cycle over vertical clusters
		{
			erode = 0;
			if (imgFilter.at<uchar>(i, j) == 255)
			{
				for (int k = -4; k < 5; k += 4)
				{
					for (int l = -4; l < 5; l += 4)
					{
						if (imgFilter.at<uchar>(i + k, j + l) == 255) erode++;
					}
				}
				if (erode < DILATE_SIZE)
				{
					for (int k = 0; k < 4; k++) //Cycle horizontally within cluster
					{
						for (int l = 0; l < 4; l++) //Cycle vertically within cluster
						{
							imgFilter.at<uchar>(i + k, j + l) = 0;
						}
					}
				}
			}
		}
	}
	for (int i = 3; i < (img.rows - 4); i++) //Cycle over horizontal clusters
	{
		for (int j = 3; j < (img.cols - 4); j++) //Cycle over vertical clusters
		{
			dilate = 0;
			if (imgFilter.at<uchar>(i, j) < 255)
			{
				for (int k = -4; k < 5; k += 4)
				{
					for (int l = -4; l < 5; l += 4)
					{
						if (imgFilter.at<uchar>(i + k, j + l) == 255) dilate++;
					}
				}
				if (dilate > ERODE_SIZE)
				{
					for (int k = 0; k < 4; k++) //Cycle horizontally within cluster
					{
						for (int l = 0; l < 4; l++) //Cycle vertically within cluster
						{
							imgFilter.at<uchar>(i + k, j + l) = 255;
						}
					}
				}
			}
		}
	}
	for (int i = 3; i < (img.cols - 4); i++) //Cycle over vertical clusters
	{
		for (int j = 3; j < (img.rows - 4); j++) //Cycle over horizontal clusters
		{
			if (imgFilter.at<uchar>(j, i) == 255) sum++;
			else if (sum > 0 && sum < 4 && j < 12)
			{
				for (sum; sum == 0; sum--)
				{
					imgFilter.at<uchar>(j, i - sum) = 0;
				}
			}
		}
	}
	for (int i = 3; i < (img.rows - 4); i++) //Cycle over horizontal clusters
	{
		for (int j = 3; j < (img.cols - 4); j++) //Cycle over vertical clusters
		{
			if (imgFilter.at<uchar>(j, i) == 255) sum++;
			else if (sum > 0 && sum < 4 && j < 12)
			{
				for (sum; sum == 0; sum--)
				{
					imgFilter.at<uchar>(j, i - sum) = 0;
				}
			}
		}
	}
}
<|endoftext|>


<commit_before>/**
 * \file
 * msa_converter.cpp: contains a class that can construct VGs from clustal MSAs
 */

#include "vg.hpp"
#include "msa_converter.hpp"

//#define debug_msa_converter

namespace vg {

using namespace std;

    MSAConverter::MSAConverter(istream& in, string format, size_t max_node_length) : max_node_length(max_node_length) {

        auto tokenize = [](string str) {
            string buf;
            vector<string> tokens;
            stringstream strm(str);
            while (strm >> buf) {
                tokens.push_back(buf);
            }
            return tokens;
        };

        if (format == "maf") {
            auto get_next_sequence_line = [](istream& in) {
                string next;

                bool got_data = getline(in, next).good();
                while (got_data && (next.empty() ? true : next[0] != 's')) {
                    got_data = getline(in, next).good();
                }
                return next;
            };

            string line = get_next_sequence_line(in);

            while (!line.empty()) {
                vector<string> tokens = tokenize(line);

                assert(tokens.size() >= 7);

                auto iter = alignments.find(tokens[1]);
                if (iter != alignments.end()) {
                    iter->second.append(tokens[6]);
                }
                else {
                    alignments[tokens[1]] = tokens[6];
                }

                line = get_next_sequence_line(in);
            }
        }
        else if (format == "clustal") {

            unordered_set<char> conservation_chars{'.', ':', '*'};

            auto is_conservation_line = [&](string& line) {
                bool conservation_line = false;
                for (char c : line) {
                    if (!isspace(c)) {
                        if (conservation_chars.count(c)) {
                            conservation_line = true;
                        }
                        else {
                            conservation_line = false;
                        }
                        break;
                    }
                }
                return conservation_line;
            };

            auto get_next_sequence_line = [&](istream& in) {
                string next;

                bool got_data = getline(in, next).good();
                bool conservation_line = is_conservation_line(next);

                while (got_data && (next.empty() || conservation_line)) {

                    got_data = getline(in, next).good();
                    conservation_line = is_conservation_line(next);

                }
                if (conservation_line || !got_data || all_of(next.begin(), next.end(), [](char c){return isspace(c);})) {
                    // hack for edge case that the final line is a conservation line or whitespace
                    next.clear();
                }
                return next;
            };

            // skip the header line
            get_next_sequence_line(in);

            string line = get_next_sequence_line(in);
            while (!line.empty()) {
                vector<string> tokens = tokenize(line);

                if (tokens.size() != 2) {
                    continue;
                }

                auto iter = alignments.find(tokens[0]);
                if (iter != alignments.end()) {
                    iter->second.append(tokens[1]);
                }
                else {
                    alignments[tokens[0]] = tokens[1];
                }

                line = get_next_sequence_line(in);
            }
        }
        else {
            cerr << "error:[MSAConverter] unsupported MSA format" << endl;
            exit(1);
        }

#ifdef debug_msa_converter
        cerr << "alignments:" << endl;
        for (const auto& aln : alignments) {
            cerr << aln.first << "\t" << aln.second << endl;
        }
#endif

        size_t aln_len = alignments.begin()->second.size();
        for (const auto& aln : alignments) {
            assert(aln.second.size() == aln_len);
        }
    }

    MSAConverter::~MSAConverter() {
        // nothing to do
    }

    VG MSAConverter::make_graph(bool keep_paths) {

        unordered_set<char> alphabet{'A', 'C', 'T', 'G', 'N', '-'};

        VG graph;

        // the node that each input sequence is extending
        unordered_map<string, Node*> current_node;

        // the path we're building for each aligned sequence
        unordered_map<string, Path*> aln_path;

        // start all of the alignments on a dummy node
        Node* dummy_node = graph.create_node("N");
        for (const auto& aln : alignments) {
            current_node[aln.first] = dummy_node;

            if (keep_paths) {
                Path* path = graph.graph.add_path();
                aln_path[aln.first] = path;
                path->set_name(aln.first);
            }
        }

        // nodes that we don't want to extend any more
        // (we never want to extend the dummy node)
        unordered_set<Node*> completed_nodes{dummy_node};

        size_t aln_len = alignments.begin()->second.size();
        for (size_t i = 0; i < aln_len; i++) {
#ifdef debug_msa_converter
            cerr << "## beginning column " << i << endl;
#endif
            unordered_map<Node*, char> forward_transitions;
            unordered_map<char, pair<unordered_set<Node*>, vector<string>>> transitions;
            for (const auto& aln : alignments) {
                char aln_char = toupper(aln.second[i]);

                if (!alphabet.count(aln_char)) {
                    cerr << "error:[MSAConverter] MSA contains non-nucleotide characters" << endl;
                    exit(1);

                }

                Node* node_here = current_node[aln.first];

                if (aln_char != '-') {
                    // this alignment is transitioning to a new aligned character
                    transitions[aln_char].first.insert(node_here);
                    transitions[aln_char].second.push_back(aln.first);

                    auto iter = forward_transitions.find(node_here);
                    if (iter != forward_transitions.end()) {
                        if (iter->second != aln_char) {
                            // this node splits in the current column, so don't extend it anymore
                            completed_nodes.insert(node_here);
                        }
                    }
                    else {
                        forward_transitions[node_here] = aln_char;
                    }
                }
                else {
                    // this alignment isn't transitioning anywhere yet

                    // we don't want to extend nodes where we'll need to attach a gap edge later
                    completed_nodes.insert(node_here);
                }
            }

            for (const auto& transition : transitions) {
#ifdef debug_msa_converter
                cerr << "transition to " << transition.first << endl;
                cerr << "from nodes:" << endl;
                for (const Node* n : transition.second.first) {
                    cerr << "\t" << n->id() << ": " << n->sequence() << endl;
                }
                cerr << "on sequences:" << endl;
                for (const string& s : transition.second.second) {
                    cerr << "\t" << s << endl;
                }
#endif
                Node* at_node;

                if (transition.second.first.size() > 1) {
                    Node* new_node = graph.create_node(string(1, transition.first));

                    for (Node* attaching_node : transition.second.first) {
                        graph.create_edge(attaching_node, new_node);
                        // we don't want to extend nodes that already have edges out of their ends
                        completed_nodes.insert(attaching_node);
                    }

                    // keep track of the fact that now we are on the new node
                    at_node = new_node;

                }
                else {
                    // there's only one node that wants to transition to this
                    // character, so we might be able to just extend the node
                    at_node = *transition.second.first.begin();

                    if (at_node->sequence().size() >= max_node_length ||
                        completed_nodes.count(at_node)) {
                        // we either want to split this node just because of length or because
                        // we've already marked it as unextendable

                        Node* new_node = graph.create_node(string(1, transition.first));

                        graph.create_edge(at_node, new_node);
                        completed_nodes.insert(at_node);

                        // keep track of the fact that now we are on the new node
                        at_node = new_node;
                    }
                    else {
                        at_node->mutable_sequence()->append(1, transition.first);
                    }
                }

                // update which node the paths are currently extending
                for (const string& name : transition.second.second) {
                    current_node[name] = at_node;

                    if (keep_paths) {
                        Path* path = aln_path[name];
                        if (path->mapping_size() == 0 ? true :
                            at_node->id() != path->mapping(path->mapping_size() - 1).position().node_id()) {
                            Mapping* mapping = path->add_mapping();
                            mapping->mutable_position()->set_node_id(at_node->id());
                        }
                    }
                }
            }

#ifdef debug_msa_converter
            cerr << "graph: " << pb2json(graph.graph) << endl;
            cerr << "node locations of sequences:" << endl;
            for (const auto& curr : current_node) {
                cerr << "\t" << curr.first << " " << curr.second->id() << endl;
            }
#endif
        }

        graph.destroy_node(dummy_node);

        return graph;
    }

}

<commit_msg>added ranks to msa converter paths<commit_after>/**
 * \file
 * msa_converter.cpp: contains a class that can construct VGs from clustal MSAs
 */

#include "vg.hpp"
#include "msa_converter.hpp"

//#define debug_msa_converter

namespace vg {

using namespace std;

    MSAConverter::MSAConverter(istream& in, string format, size_t max_node_length) : max_node_length(max_node_length) {

        auto tokenize = [](string str) {
            string buf;
            vector<string> tokens;
            stringstream strm(str);
            while (strm >> buf) {
                tokens.push_back(buf);
            }
            return tokens;
        };

        if (format == "maf") {
            auto get_next_sequence_line = [](istream& in) {
                string next;

                bool got_data = getline(in, next).good();
                while (got_data && (next.empty() ? true : next[0] != 's')) {
                    got_data = getline(in, next).good();
                }
                return next;
            };

            string line = get_next_sequence_line(in);

            while (!line.empty()) {
                vector<string> tokens = tokenize(line);

                assert(tokens.size() >= 7);

                auto iter = alignments.find(tokens[1]);
                if (iter != alignments.end()) {
                    iter->second.append(tokens[6]);
                }
                else {
                    alignments[tokens[1]] = tokens[6];
                }

                line = get_next_sequence_line(in);
            }
        }
        else if (format == "clustal") {

            unordered_set<char> conservation_chars{'.', ':', '*'};

            auto is_conservation_line = [&](string& line) {
                bool conservation_line = false;
                for (char c : line) {
                    if (!isspace(c)) {
                        if (conservation_chars.count(c)) {
                            conservation_line = true;
                        }
                        else {
                            conservation_line = false;
                        }
                        break;
                    }
                }
                return conservation_line;
            };

            auto get_next_sequence_line = [&](istream& in) {
                string next;

                bool got_data = getline(in, next).good();
                bool conservation_line = is_conservation_line(next);

                while (got_data && (next.empty() || conservation_line)) {

                    got_data = getline(in, next).good();
                    conservation_line = is_conservation_line(next);

                }
                if (conservation_line || !got_data || all_of(next.begin(), next.end(), [](char c){return isspace(c);})) {
                    // hack for edge case that the final line is a conservation line or whitespace
                    next.clear();
                }
                return next;
            };

            // skip the header line
            get_next_sequence_line(in);

            string line = get_next_sequence_line(in);
            while (!line.empty()) {
                vector<string> tokens = tokenize(line);

                if (tokens.size() != 2) {
                    continue;
                }

                auto iter = alignments.find(tokens[0]);
                if (iter != alignments.end()) {
                    iter->second.append(tokens[1]);
                }
                else {
                    alignments[tokens[0]] = tokens[1];
                }

                line = get_next_sequence_line(in);
            }
        }
        else {
            cerr << "error:[MSAConverter] unsupported MSA format" << endl;
            exit(1);
        }

#ifdef debug_msa_converter
        cerr << "alignments:" << endl;
        for (const auto& aln : alignments) {
            cerr << aln.first << "\t" << aln.second << endl;
        }
#endif

        size_t aln_len = alignments.begin()->second.size();
        for (const auto& aln : alignments) {
            assert(aln.second.size() == aln_len);
        }
    }

    MSAConverter::~MSAConverter() {
        // nothing to do
    }

    VG MSAConverter::make_graph(bool keep_paths) {

        unordered_set<char> alphabet{'A', 'C', 'T', 'G', 'N', '-'};

        VG graph;

        // the node that each input sequence is extending
        unordered_map<string, Node*> current_node;

        // the path we're building for each aligned sequence
        unordered_map<string, Path*> aln_path;

        // start all of the alignments on a dummy node
        Node* dummy_node = graph.create_node("N");
        for (const auto& aln : alignments) {
            current_node[aln.first] = dummy_node;

            if (keep_paths) {
                Path* path = graph.graph.add_path();
                aln_path[aln.first] = path;
                path->set_name(aln.first);
            }
        }

        // nodes that we don't want to extend any more
        // (we never want to extend the dummy node)
        unordered_set<Node*> completed_nodes{dummy_node};

        size_t aln_len = alignments.begin()->second.size();
        for (size_t i = 0; i < aln_len; i++) {
#ifdef debug_msa_converter
            cerr << "## beginning column " << i << endl;
#endif
            unordered_map<Node*, char> forward_transitions;
            unordered_map<char, pair<unordered_set<Node*>, vector<string>>> transitions;
            for (const auto& aln : alignments) {
                char aln_char = toupper(aln.second[i]);

                if (!alphabet.count(aln_char)) {
                    cerr << "error:[MSAConverter] MSA contains non-nucleotide characters" << endl;
                    exit(1);

                }

                Node* node_here = current_node[aln.first];

                if (aln_char != '-') {
                    // this alignment is transitioning to a new aligned character
                    transitions[aln_char].first.insert(node_here);
                    transitions[aln_char].second.push_back(aln.first);

                    auto iter = forward_transitions.find(node_here);
                    if (iter != forward_transitions.end()) {
                        if (iter->second != aln_char) {
                            // this node splits in the current column, so don't extend it anymore
                            completed_nodes.insert(node_here);
                        }
                    }
                    else {
                        forward_transitions[node_here] = aln_char;
                    }
                }
                else {
                    // this alignment isn't transitioning anywhere yet

                    // we don't want to extend nodes where we'll need to attach a gap edge later
                    completed_nodes.insert(node_here);
                }
            }

            for (const auto& transition : transitions) {
#ifdef debug_msa_converter
                cerr << "transition to " << transition.first << endl;
                cerr << "from nodes:" << endl;
                for (const Node* n : transition.second.first) {
                    cerr << "\t" << n->id() << ": " << n->sequence() << endl;
                }
                cerr << "on sequences:" << endl;
                for (const string& s : transition.second.second) {
                    cerr << "\t" << s << endl;
                }
#endif
                Node* at_node;

                if (transition.second.first.size() > 1) {
                    Node* new_node = graph.create_node(string(1, transition.first));

                    for (Node* attaching_node : transition.second.first) {
                        graph.create_edge(attaching_node, new_node);
                        // we don't want to extend nodes that already have edges out of their ends
                        completed_nodes.insert(attaching_node);
                    }

                    // keep track of the fact that now we are on the new node
                    at_node = new_node;

                }
                else {
                    // there's only one node that wants to transition to this
                    // character, so we might be able to just extend the node
                    at_node = *transition.second.first.begin();

                    if (at_node->sequence().size() >= max_node_length ||
                        completed_nodes.count(at_node)) {
                        // we either want to split this node just because of length or because
                        // we've already marked it as unextendable

                        Node* new_node = graph.create_node(string(1, transition.first));

                        graph.create_edge(at_node, new_node);
                        completed_nodes.insert(at_node);

                        // keep track of the fact that now we are on the new node
                        at_node = new_node;
                    }
                    else {
                        at_node->mutable_sequence()->append(1, transition.first);
                    }
                }

                // update which node the paths are currently extending
                for (const string& name : transition.second.second) {
                    current_node[name] = at_node;

                    if (keep_paths) {
                        Path* path = aln_path[name];
                        if (path->mapping_size() == 0 ? true :
                            at_node->id() != path->mapping(path->mapping_size() - 1).position().node_id()) {
                            Mapping* mapping = path->add_mapping();
                            mapping->mutable_position()->set_node_id(at_node->id());
                            mapping->set_rank(path->mapping_size());
                        }
                    }
                }
            }

#ifdef debug_msa_converter
            cerr << "graph: " << pb2json(graph.graph) << endl;
            cerr << "node locations of sequences:" << endl;
            for (const auto& curr : current_node) {
                cerr << "\t" << curr.first << " " << curr.second->id() << endl;
            }
#endif
        }

        graph.destroy_node(dummy_node);

        return graph;
    }

}

<|endoftext|>


<commit_before>// Copyright 2014, Max Planck Institute for Intelligent Systems.
// Distributed under the BSD 3-Clause license.
// (See accompanying file LICENSE.txt or copy at
// http://opensource.org/licenses/BSD-3-Clause)

//!@file
//! Mex wrapper file for robust PCA

#include "mex.h"

#include <boost/numeric/ublas/storage.hpp>

#include <include/robust_pca.hpp>
#include <include/private/boost_ublas_matlab_helper.hpp>
#include <include/private/boost_ublas_matrix_helper.hpp>

//! Implements allocate and free.
template <class T>
struct matlab_matrix_allocation;

template <>
struct matlab_matrix_allocation<double>
{
  static mxArray * allocate(size_t s)
  {
    return mxCreateDoubleMatrix(s, 1, mxREAL);
  }

  static void free(mxArray *mat)
  {
    mxDestroyArray(mat);
  }
};

//! An helper class that implements the storage concept of boost::ublas
//! and performs the allocation on matlab side. It is also possible
//! to provide a matlab array.
template <class T>
class matlab_matrix_storage
{
  typedef T& reference;

  //! Default constructible
  matlab_matrix_storage() : pData(0)
  {
  }

  //! Size constructible
  matlab_matrix_storage(size_t s) : pData(0)
  {
    mxArray *v = matlab_matrix_allocation<T>::allocate(s);

  }

  //! Random access container
  reference operator[](size_t i)
  {
    return pData[i];
  }

private:
  T* pData;
};

template <class output_type, class input_type>
output_type get_matlab_array_value_dispatch(mxArray const* array_, size_t index_row, size_t index_column)
{
  input_type* p_array = static_cast<input_type*>(mxGetData(array_));
  if(p_array == 0)
  {
    throw std::runtime_error("Unable to retrieve a pointer to the typed array");
  }

  // column major
  return p_array[index_row + mxGetN(array_) * index_column];
}

template <class output_type>
output_type get_matlab_array_value(mxArray const* array_, size_t index_row, size_t index_column)
{
  assert(index_row < mxGetM(array_));
  assert(index_column < mxGetN(array_));

  mxClassID classId = mxGetClassID(array_);
  switch(classId)
  {
  case mxDOUBLE_CLASS:
    return get_matlab_array_value_dispatch<output_type, double>(array_, index_row, index_column);
  case mxSINGLE_CLASS:
    return get_matlab_array_value_dispatch<output_type, float>(array_, index_row, index_column);
  default:
    throw std::runtime_error("Unable to dispatch to the correct type");
  }
}

struct s_algorithm_configuration
{
  size_t rows;
  size_t columns;

  size_t max_dimension;
  size_t max_iterations;
  size_t max_chunk_size;
  size_t nb_processors;
  double trimming_percentage;

  // we should also add the initial value of the eigen vectors
};

template <class input_array_type>
bool robust_pca_dispatch(
  mxArray const* X,
  s_algorithm_configuration const& algorithm_configuration,
  mxArray *outputMatrix)
{
  namespace ub = boost::numeric::ublas;

  using namespace robust_pca;
  using namespace robust_pca::ublas_adaptor;
  using namespace robust_pca::ublas_matlab_helper;

  typedef external_storage_adaptor<input_array_type> input_storage_t;
  typedef ub::matrix<input_array_type, ub::column_major, input_storage_t> input_matrix_t;

  typedef external_storage_adaptor<double> output_storage_t;
  typedef ub::matrix<double, ub::column_major, output_storage_t> output_matrix_t;

  const size_t &columns = algorithm_configuration.columns;
  const size_t &rows = algorithm_configuration.rows;
  const size_t &max_dimension = algorithm_configuration.max_dimension;
  const size_t &max_iterations = algorithm_configuration.max_iterations;
  const size_t dimension = columns;

  // input data matrix, external storage.
  input_storage_t input_storage(rows*columns, mxGetPr(X));
  input_matrix_t input_data(rows, columns, input_storage);

  // output data matrix, also external storage for uBlas
  output_storage_t storageOutput(dimension * max_dimension, mxGetPr(outputMatrix));
  output_matrix_t output_eigen_vectors(max_dimension, dimension, storageOutput);

  // this is the form of the data extracted from the storage
  typedef ub::vector<double> data_t;
  typedef robust_pca_impl< data_t > robust_pca_t;

  typedef row_iter<const input_matrix_t> const_input_row_iter_t;
  typedef row_iter<output_matrix_t> output_row_iter_t;

  // should be matlab style
  std::vector<data_t> temporary_data(rows);

  // main instance
  robust_pca_t instance;

  if(algorithm_configuration.nb_processors > 0)
  {
    if(!instance.set_nb_processors(algorithm_configuration.nb_processors))
    {
      mexWarnMsgTxt("Incorrect number of processors. Please consult the documentation.");
      return false;
    }
  }

  if(algorithm_configuration.nb_processors > 0)
  {
    if(!instance.set_max_chunk_size(algorithm_configuration.max_chunk_size))
    {
	    mexWarnMsgTxt("Incorrect chunk size. Please consult the documentation.");
      return false;
    }
  }

  return instance.batch_process(
    max_iterations,
    max_dimension,
    const_input_row_iter_t(input_data, 0),
    const_input_row_iter_t(input_data, input_data.size1()),
    temporary_data.begin(),
    output_row_iter_t(output_eigen_vectors, 0));

}

template <class input_array_type>
bool robust_pca_trimming_dispatch(
  mxArray const* X,
  s_algorithm_configuration const& algorithm_configuration,
  mxArray *outputMatrix)
{
  namespace ub = boost::numeric::ublas;

  using namespace robust_pca;
  using namespace robust_pca::ublas_adaptor;
  using namespace robust_pca::ublas_matlab_helper;

  typedef external_storage_adaptor<input_array_type> input_storage_t;
  typedef ub::matrix<input_array_type, ub::column_major, input_storage_t> input_matrix_t;

  typedef external_storage_adaptor<double> output_storage_t;
  typedef ub::matrix<double, ub::column_major, output_storage_t> output_matrix_t;

  const size_t &columns = algorithm_configuration.columns;
  const size_t &rows = algorithm_configuration.rows;
  const size_t &max_dimension = algorithm_configuration.max_dimension;
  const size_t &max_iterations = algorithm_configuration.max_iterations;

  const size_t dimension = columns;

  // input data matrix, external storage.
  input_storage_t input_storage(rows*columns, mxGetPr(X));
  input_matrix_t input_data(rows, columns, input_storage);

  // output data matrix, also external storage for uBlas
  output_storage_t storageOutput(dimension * max_dimension, mxGetPr(outputMatrix));
  output_matrix_t output_eigen_vectors(max_dimension, dimension, storageOutput);

  // this is the form of the data extracted from the storage
  typedef ub::vector<double> data_t;
  typedef robust_pca_with_trimming_impl< data_t > robust_pca_t;

  typedef row_iter<const input_matrix_t> const_input_row_iter_t;
  typedef row_iter<output_matrix_t> output_row_iter_t;

  // should be matlab style
  std::vector<data_t> temporary_data(rows);

  // main instance
  robust_pca_t instance(algorithm_configuration.trimming_percentage / 200, 1 - algorithm_configuration.trimming_percentage / 200);

  return instance.batch_process(
    max_iterations,
    max_dimension,
    const_input_row_iter_t(input_data, 0),
    const_input_row_iter_t(input_data, input_data.size1()),
    temporary_data.begin(),
    output_row_iter_t(output_eigen_vectors, 0));

}

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{

  // arguments checking
  if (nrhs < 1 || nrhs > 4)
  {
	  mexErrMsgTxt("Incorrect number of arguments. Please consult the documentation.");
  }

  const mxArray* const X = prhs[0];
  assert(X);

  // checking the format of the data
  if (!mxIsDouble(X) && !mxIsSingle(X))
  {
	  mexErrMsgTxt("Unsupported input format (floating point required)");
  }

  if(mxIsComplex(X))
  {
    mexErrMsgTxt("Unsupported format (scalar data required)");
  }

  s_algorithm_configuration config;

  // Check the dimensions of inputs
  config.rows = mxGetM(X);
  config.columns = mxGetN(X);

  const size_t &rows = config.rows;
  const size_t &columns = config.columns;
  size_t &max_dimension = config.max_dimension;
  double &trimming_percentage = config.trimming_percentage;
  size_t &max_chunk_size = config.max_chunk_size;
  size_t &nb_iterations_max = config.max_iterations;
  size_t &nb_processing_threads = config.nb_processors;

  size_t dimension = columns;

  // third argument is the optional trimming percentage
  bool b_trimming = false;
  trimming_percentage = -1;
  if(nrhs >= 2)
  {
    const mxArray* const trimmingArray = prhs[1];
    if(!mxIsNumeric(trimmingArray))
    {
      mexErrMsgTxt("Erroneous argument for the trimming percentage (non numeric argument)");
    }

    if(mxIsEmpty(trimmingArray))
    {
      mexErrMsgTxt("Erroneous argument for the trimming percentage (empty value)");
    }

    if(mxGetNumberOfElements(trimmingArray) > 1)
    {
      mexErrMsgTxt("Erroneous argument for the trimming percentage (non scalar)");
    }

    mxClassID classId = mxGetClassID(trimmingArray);
    if(classId == mxDOUBLE_CLASS || classId == mxSINGLE_CLASS)
    {
      //mexErrMsgTxt("Erroneous argument for the maximal dimension specification (floating point type)");
    }

    b_trimming = true;
    trimming_percentage = mxGetScalar(trimmingArray);

    if(trimming_percentage < 0 || trimming_percentage > 100)
    {
      mexErrMsgTxt("Erroneous argument for the trimming percentage (not within the range [0, 100])");
    }

    b_trimming = trimming_percentage > 0 && trimming_percentage < 100;
  }

  nb_iterations_max = 1000;
  max_chunk_size = std::numeric_limits<size_t>::max();
  nb_processing_threads = 1;
  max_dimension = dimension;

  if(nrhs == 3)
  {
    const mxArray* const algorithmConfiguration = prhs[2];

    if(!mxIsStruct(algorithmConfiguration))
    {
      mexErrMsgTxt("Erroneous argument for the algorithm configuration (not a structure)");
    }

    mxArray *nb_iteration_array = mxGetField(algorithmConfiguration, 0, "nb_iterations_max");
    if(nb_iteration_array != 0)
    {
      nb_iterations_max = static_cast<int>(mxGetScalar(nb_iteration_array) + 0.5);
    }

    mxArray *max_chunk_size_array = mxGetField(algorithmConfiguration, 0, "max_chunk_size");
    if(max_chunk_size_array != 0)
    {
      max_chunk_size = static_cast<size_t>(mxGetScalar(max_chunk_size_array) + 0.5);
    }

    mxArray *nb_processing_threads_array = mxGetField(algorithmConfiguration, 0, "nb_processing_threads");
    if(nb_processing_threads_array != 0)
    {
      nb_processing_threads = static_cast<size_t>(mxGetScalar(nb_processing_threads_array) + 0.5);
    }

    mxArray *nb_max_dimensions = mxGetField(algorithmConfiguration, 0, "max_dimensions");
    if(nb_max_dimensions != 0)
    {
      max_dimension = static_cast<size_t>(mxGetScalar(nb_max_dimensions) + 0.5);
    }
  }

  // TODO put the dimension
  // for the library to work, we need to allocate some temporary storage
  // we also allocate the output if given
  plhs[0] = mxCreateDoubleMatrix(dimension, max_dimension, mxREAL);
  mxArray *outputMatrix = plhs[0];
  assert(outputMatrix);

  bool result = false;
  switch(mxGetClassID(X))
  {
  case mxDOUBLE_CLASS:
  {
    if(!b_trimming)
    {
      result = robust_pca_dispatch<double>(X, config, outputMatrix);
    }
    else
    {
      result = robust_pca_trimming_dispatch<double>(X, config, outputMatrix);
    }

    break;
  }
  default:
    break;
  }

  if(!result)
  {
    mexErrMsgTxt("Robust PCA: an error occurred in the call of the function.");
  }

}<commit_msg>cleaning<commit_after>// Copyright 2014, Max Planck Institute for Intelligent Systems.
// Distributed under the BSD 3-Clause license.
// (See accompanying file LICENSE.txt or copy at
// http://opensource.org/licenses/BSD-3-Clause)

//!@file
//! Mex wrapper file for robust PCA

#include "mex.h"

#include <boost/numeric/ublas/storage.hpp>

#include <include/robust_pca.hpp>
#include <include/private/boost_ublas_matlab_helper.hpp>
#include <include/private/boost_ublas_matrix_helper.hpp>

//! Implements allocate and free.
template <class T>
struct matlab_matrix_allocation;

template <>
struct matlab_matrix_allocation<double>
{
  static mxArray * allocate(size_t s)
  {
    return mxCreateDoubleMatrix(s, 1, mxREAL);
  }

  static void free(mxArray *mat)
  {
    mxDestroyArray(mat);
  }
};

template <class output_type, class input_type>
output_type get_matlab_array_value_dispatch(mxArray const* array_, size_t index_row, size_t index_column)
{
  input_type* p_array = static_cast<input_type*>(mxGetData(array_));
  if(p_array == 0)
  {
    throw std::runtime_error("Unable to retrieve a pointer to the typed array");
  }

  // column major
  return p_array[index_row + mxGetN(array_) * index_column];
}

template <class output_type>
output_type get_matlab_array_value(mxArray const* array_, size_t index_row, size_t index_column)
{
  assert(index_row < mxGetM(array_));
  assert(index_column < mxGetN(array_));

  mxClassID classId = mxGetClassID(array_);
  switch(classId)
  {
  case mxDOUBLE_CLASS:
    return get_matlab_array_value_dispatch<output_type, double>(array_, index_row, index_column);
  case mxSINGLE_CLASS:
    return get_matlab_array_value_dispatch<output_type, float>(array_, index_row, index_column);
  default:
    throw std::runtime_error("Unable to dispatch to the correct type");
  }
}

struct s_algorithm_configuration
{
  size_t rows;
  size_t columns;

  size_t max_dimension;
  size_t max_iterations;
  size_t max_chunk_size;
  size_t nb_processors;
  double trimming_percentage;

  // we should also add the initial value of the eigen vectors
};

template <class input_array_type>
bool robust_pca_dispatch(
  mxArray const* X,
  s_algorithm_configuration const& algorithm_configuration,
  mxArray *outputMatrix)
{
  namespace ub = boost::numeric::ublas;

  using namespace robust_pca;
  using namespace robust_pca::ublas_adaptor;
  using namespace robust_pca::ublas_matlab_helper;

  typedef external_storage_adaptor<input_array_type> input_storage_t;
  typedef ub::matrix<input_array_type, ub::column_major, input_storage_t> input_matrix_t;

  typedef external_storage_adaptor<double> output_storage_t;
  typedef ub::matrix<double, ub::column_major, output_storage_t> output_matrix_t;

  const size_t &columns = algorithm_configuration.columns;
  const size_t &rows = algorithm_configuration.rows;
  const size_t &max_dimension = algorithm_configuration.max_dimension;
  const size_t &max_iterations = algorithm_configuration.max_iterations;
  const size_t dimension = columns;

  // input data matrix, external storage.
  input_storage_t input_storage(rows*columns, mxGetPr(X));
  input_matrix_t input_data(rows, columns, input_storage);

  // output data matrix, also external storage for uBlas
  output_storage_t storageOutput(dimension * max_dimension, mxGetPr(outputMatrix));
  output_matrix_t output_eigen_vectors(max_dimension, dimension, storageOutput);

  // this is the form of the data extracted from the storage
  typedef ub::vector<double> data_t;
  typedef robust_pca_impl< data_t > robust_pca_t;

  typedef row_iter<const input_matrix_t> const_input_row_iter_t;
  typedef row_iter<output_matrix_t> output_row_iter_t;

  // should be matlab style
  std::vector<data_t> temporary_data(rows);

  // main instance
  robust_pca_t instance;

  if(algorithm_configuration.nb_processors > 0)
  {
    if(!instance.set_nb_processors(algorithm_configuration.nb_processors))
    {
      mexWarnMsgTxt("Incorrect number of processors. Please consult the documentation.");
      return false;
    }
  }

  if(algorithm_configuration.nb_processors > 0)
  {
    if(!instance.set_max_chunk_size(algorithm_configuration.max_chunk_size))
    {
	    mexWarnMsgTxt("Incorrect chunk size. Please consult the documentation.");
      return false;
    }
  }

  return instance.batch_process(
    max_iterations,
    max_dimension,
    const_input_row_iter_t(input_data, 0),
    const_input_row_iter_t(input_data, input_data.size1()),
    temporary_data.begin(),
    output_row_iter_t(output_eigen_vectors, 0));

}

template <class input_array_type>
bool robust_pca_trimming_dispatch(
  mxArray const* X,
  s_algorithm_configuration const& algorithm_configuration,
  mxArray *outputMatrix)
{
  namespace ub = boost::numeric::ublas;

  using namespace robust_pca;
  using namespace robust_pca::ublas_adaptor;
  using namespace robust_pca::ublas_matlab_helper;

  typedef external_storage_adaptor<input_array_type> input_storage_t;
  typedef ub::matrix<input_array_type, ub::column_major, input_storage_t> input_matrix_t;

  typedef external_storage_adaptor<double> output_storage_t;
  typedef ub::matrix<double, ub::column_major, output_storage_t> output_matrix_t;

  const size_t &columns = algorithm_configuration.columns;
  const size_t &rows = algorithm_configuration.rows;
  const size_t &max_dimension = algorithm_configuration.max_dimension;
  const size_t &max_iterations = algorithm_configuration.max_iterations;

  const size_t dimension = columns;

  // input data matrix, external storage.
  input_storage_t input_storage(rows*columns, mxGetPr(X));
  input_matrix_t input_data(rows, columns, input_storage);

  // output data matrix, also external storage for uBlas
  output_storage_t storageOutput(dimension * max_dimension, mxGetPr(outputMatrix));
  output_matrix_t output_eigen_vectors(max_dimension, dimension, storageOutput);

  // this is the form of the data extracted from the storage
  typedef ub::vector<double> data_t;
  typedef robust_pca_with_trimming_impl< data_t > robust_pca_t;

  typedef row_iter<const input_matrix_t> const_input_row_iter_t;
  typedef row_iter<output_matrix_t> output_row_iter_t;

  // should be matlab style
  std::vector<data_t> temporary_data(rows);

  // main instance
  robust_pca_t instance(algorithm_configuration.trimming_percentage / 200, 1 - algorithm_configuration.trimming_percentage / 200);

  return instance.batch_process(
    max_iterations,
    max_dimension,
    const_input_row_iter_t(input_data, 0),
    const_input_row_iter_t(input_data, input_data.size1()),
    temporary_data.begin(),
    output_row_iter_t(output_eigen_vectors, 0));

}

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{

  // arguments checking
  if (nrhs < 1 || nrhs > 4)
  {
	  mexErrMsgTxt("Incorrect number of arguments. Please consult the documentation.");
  }

  const mxArray* const X = prhs[0];
  assert(X);

  // checking the format of the data
  if (!mxIsDouble(X) && !mxIsSingle(X))
  {
	  mexErrMsgTxt("Unsupported input format (floating point required)");
  }

  if(mxIsComplex(X))
  {
    mexErrMsgTxt("Unsupported format (scalar data required)");
  }

  s_algorithm_configuration config;

  // Check the dimensions of inputs
  config.rows = mxGetM(X);
  config.columns = mxGetN(X);

  const size_t &columns = config.columns;
  size_t &max_dimension = config.max_dimension;
  double &trimming_percentage = config.trimming_percentage;
  size_t &max_chunk_size = config.max_chunk_size;
  size_t &nb_iterations_max = config.max_iterations;
  size_t &nb_processing_threads = config.nb_processors;

  size_t dimension = columns;

  // third argument is the optional trimming percentage
  bool b_trimming = false;
  trimming_percentage = -1;
  if(nrhs >= 2)
  {
    const mxArray* const trimmingArray = prhs[1];
    if(!mxIsNumeric(trimmingArray))
    {
      mexErrMsgTxt("Erroneous argument for the trimming percentage (non numeric argument)");
    }

    if(mxIsEmpty(trimmingArray))
    {
      mexErrMsgTxt("Erroneous argument for the trimming percentage (empty value)");
    }

    if(mxGetNumberOfElements(trimmingArray) > 1)
    {
      mexErrMsgTxt("Erroneous argument for the trimming percentage (non scalar)");
    }

    mxClassID classId = mxGetClassID(trimmingArray);
    if(classId == mxDOUBLE_CLASS || classId == mxSINGLE_CLASS)
    {
      //mexErrMsgTxt("Erroneous argument for the maximal dimension specification (floating point type)");
    }

    b_trimming = true;
    trimming_percentage = mxGetScalar(trimmingArray);

    if(trimming_percentage < 0 || trimming_percentage > 100)
    {
      mexErrMsgTxt("Erroneous argument for the trimming percentage (not within the range [0, 100])");
    }

    b_trimming = trimming_percentage > 0 && trimming_percentage < 100;
  }

  nb_iterations_max = 1000;
  max_chunk_size = std::numeric_limits<size_t>::max();
  nb_processing_threads = 1;
  max_dimension = dimension;

  if(nrhs == 3)
  {
    const mxArray* const algorithmConfiguration = prhs[2];

    if(!mxIsStruct(algorithmConfiguration))
    {
      mexErrMsgTxt("Erroneous argument for the algorithm configuration (not a structure)");
    }

    mxArray *nb_iteration_array = mxGetField(algorithmConfiguration, 0, "nb_iterations_max");
    if(nb_iteration_array != 0)
    {
      nb_iterations_max = static_cast<int>(mxGetScalar(nb_iteration_array) + 0.5);
    }

    mxArray *max_chunk_size_array = mxGetField(algorithmConfiguration, 0, "max_chunk_size");
    if(max_chunk_size_array != 0)
    {
      max_chunk_size = static_cast<size_t>(mxGetScalar(max_chunk_size_array) + 0.5);
    }

    mxArray *nb_processing_threads_array = mxGetField(algorithmConfiguration, 0, "nb_processing_threads");
    if(nb_processing_threads_array != 0)
    {
      nb_processing_threads = static_cast<size_t>(mxGetScalar(nb_processing_threads_array) + 0.5);
    }

    mxArray *nb_max_dimensions = mxGetField(algorithmConfiguration, 0, "max_dimensions");
    if(nb_max_dimensions != 0)
    {
      max_dimension = static_cast<size_t>(mxGetScalar(nb_max_dimensions) + 0.5);
    }
  }

  // TODO put the dimension
  // for the library to work, we need to allocate some temporary storage
  // we also allocate the output if given
  plhs[0] = mxCreateDoubleMatrix(dimension, max_dimension, mxREAL);
  mxArray *outputMatrix = plhs[0];
  assert(outputMatrix);

  bool result = false;
  switch(mxGetClassID(X))
  {
  case mxDOUBLE_CLASS:
  {
    if(!b_trimming)
    {
      result = robust_pca_dispatch<double>(X, config, outputMatrix);
    }
    else
    {
      result = robust_pca_trimming_dispatch<double>(X, config, outputMatrix);
    }

    break;
  }
  default:
    break;
  }

  if(!result)
  {
    mexErrMsgTxt("Robust PCA: an error occurred in the call of the function.");
  }

}<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: TableDeco.hxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: oj $ $Date: 2001-04-23 10:07:41 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _DBA_CORE_TABLEDECORATOR_HXX_
#define _DBA_CORE_TABLEDECORATOR_HXX_

#ifndef _COM_SUN_STAR_SDBCX_XCOLUMNSSUPPLIER_HPP_
#include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBCX_XDATADESCRIPTORFACTORY_HPP_
#include <com/sun/star/sdbcx/XDataDescriptorFactory.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBCX_XINDEXESSUPPLIER_HPP_
#include <com/sun/star/sdbcx/XIndexesSupplier.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBCX_XKEYSSUPPLIER_HPP_
#include <com/sun/star/sdbcx/XKeysSupplier.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBCX_XRENAME_HPP_
#include <com/sun/star/sdbcx/XRename.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBCX_XALTERTABLE_HPP_
#include <com/sun/star/sdbcx/XAlterTable.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XSERVICEINFO_HPP_
#include <com/sun/star/lang/XServiceInfo.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBC_XROW_HPP_
#include <com/sun/star/sdbc/XRow.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBC_XCONNECTION_HPP_
#include <com/sun/star/sdbc/XConnection.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XUNOTUNNEL_HPP_
#include <com/sun/star/lang/XUnoTunnel.hpp>
#endif
#ifndef _CPPUHELPER_COMPBASE9_HXX_
#include <cppuhelper/compbase9.hxx>
#endif
#ifndef _CPPUHELPER_IMPLBASE5_HXX_
#include <cppuhelper/implbase5.hxx>
#endif
#ifndef _DBASHARED_APITOOLS_HXX_
#include "apitools.hxx"
#endif
#ifndef _DBA_CORE_DATASETTINGS_HXX_
#include "datasettings.hxx"
#endif
#ifndef _DBA_COREAPI_COLUMN_HXX_
#include <column.hxx>
#endif
#ifndef _CONNECTIVITY_COMMONTOOLS_HXX_
#include <connectivity/CommonTools.hxx>
#endif
#ifndef _CONNECTIVITY_SDBCX_IREFRESHABLE_HXX_
#include <connectivity/sdbcx/IRefreshable.hxx>
#endif
#ifndef _DBA_CORE_CONFIGURATIONFLUSHABLE_HXX_
#include "configurationflushable.hxx"
#endif

namespace dbaccess
{
    typedef ::cppu::WeakComponentImplHelper9<   ::com::sun::star::sdbcx::XColumnsSupplier,
                                                ::com::sun::star::sdbcx::XKeysSupplier,
                                                ::com::sun::star::container::XNamed,
                                                ::com::sun::star::lang::XServiceInfo,
                                                ::com::sun::star::sdbcx::XDataDescriptorFactory,
                                                ::com::sun::star::sdbcx::XIndexesSupplier,
                                                ::com::sun::star::sdbcx::XRename,
                                                ::com::sun::star::sdbcx::XAlterTable,
                                                ::com::sun::star::lang::XUnoTunnel> OTableDescriptor_BASE;
    //==========================================================================
    //= OTables
    //==========================================================================
    class ODBTableDecorator;
    typedef ::comphelper::OPropertyArrayUsageHelper< ODBTableDecorator >    ODBTableDecorator_PROP;

    class ODBTableDecorator :public comphelper::OBaseMutex
                            ,public ODataSettings //ODataSettings_Base
                            ,public OConfigurationFlushable
                            ,public OTableDescriptor_BASE
                            ,public IColumnFactory
                            ,public ::connectivity::sdbcx::IRefreshableColumns
                            ,public ODBTableDecorator_PROP
    {
        void fillPrivileges() const;
    protected:
        ::com::sun::star::uno::Reference< ::com::sun::star::sdbcx::XColumnsSupplier >   m_xTable;
        ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XDatabaseMetaData >   m_xMetaData;
    // <properties>
        sal_Int32                                                                       m_nPrivileges;
    // </properties>
        ::connectivity::sdbcx::OCollection*                                             m_pColumns;

        // IColumnFactory
        virtual OColumn*    createColumn(const ::rtl::OUString& _rName) const;
        virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > createEmptyObject();
        virtual void refreshColumns();

        virtual ::cppu::IPropertyArrayHelper* createArrayHelper() const;
        virtual ::cppu::IPropertyArrayHelper & SAL_CALL getInfoHelper();
        // OConfigurationFlushable
        virtual void flush_NoBroadcast_NoCommit();

        // OPropertySetHelper
        virtual sal_Bool SAL_CALL convertFastPropertyValue(
                            ::com::sun::star::uno::Any & rConvertedValue,
                            ::com::sun::star::uno::Any & rOldValue,
                            sal_Int32 nHandle,
                            const ::com::sun::star::uno::Any& rValue )
                                throw (::com::sun::star::lang::IllegalArgumentException);
        virtual void SAL_CALL getFastPropertyValue(::com::sun::star::uno::Any& rValue, sal_Int32 nHandle) const;
        virtual void SAL_CALL setFastPropertyValue_NoBroadcast(
                                sal_Int32 nHandle,
                                const ::com::sun::star::uno::Any& rValue
                                                 )
                                                 throw (::com::sun::star::uno::Exception);
    public:
        /** constructs a wrapper supporting the com.sun.star.sdb.Table service.

            @param          _rxConn         the connection the table belongs to
            @param          _rxTable        the table from the driver can be null
        */
        ODBTableDecorator(const OConfigurationNode& _rTableConfig,
                const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XDatabaseMetaData >& _rxConn,
                const ::com::sun::star::uno::Reference< ::com::sun::star::sdbcx::XColumnsSupplier >& _rxTable)
            throw(::com::sun::star::sdbc::SQLException);

        ODBTableDecorator(  const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XDatabaseMetaData >& _rxConn,
                    const ::com::sun::star::uno::Reference< ::com::sun::star::sdbcx::XColumnsSupplier >& _rxNewTable)
            throw(::com::sun::star::sdbc::SQLException);
        virtual ~ODBTableDecorator();

        // ODescriptor
        virtual void construct();

        //XInterface
        virtual ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException);
        //XTypeProvider
        virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL getTypes(  ) throw(::com::sun::star::uno::RuntimeException);
        virtual ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId() throw (::com::sun::star::uno::RuntimeException);

    // OComponentHelper
        virtual void SAL_CALL disposing(void);

    // ::com::sun::star::lang::XServiceInfo
        DECLARE_SERVICE_INFO();
        // XInterface
        DECLARE_CTY_DEFAULTS(OTableDescriptor_BASE);

        // XPropertySet
        virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo(  ) throw(::com::sun::star::uno::RuntimeException);
    // ::com::sun::star::sdbcx::XRename,
        virtual void SAL_CALL rename( const ::rtl::OUString& _rNewName ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::container::ElementExistException, ::com::sun::star::uno::RuntimeException);

    // ::com::sun::star::sdbcx::XAlterTable,
        virtual void SAL_CALL alterColumnByName( const ::rtl::OUString& _rName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& _rxDescriptor ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::container::NoSuchElementException, ::com::sun::star::uno::RuntimeException);
        virtual void SAL_CALL alterColumnByIndex( sal_Int32 _nIndex, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& _rxDescriptor ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);

        // XNamed
        virtual ::rtl::OUString SAL_CALL getName() throw(::com::sun::star::uno::RuntimeException);
        virtual void SAL_CALL setName( const ::rtl::OUString& aName ) throw (::com::sun::star::uno::RuntimeException)
        {
        }
        // com::sun::star::lang::XUnoTunnel
        virtual sal_Int64 SAL_CALL getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& aIdentifier ) throw(::com::sun::star::uno::RuntimeException);

        ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XDatabaseMetaData> getMetaData() const { return m_xMetaData; }
        ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection> getConnection() const { return m_xMetaData->getConnection(); }

        // XColumnsSupplier
        virtual ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess > SAL_CALL getColumns(  ) throw (::com::sun::star::uno::RuntimeException);
        // XKeysSupplier
        virtual ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexAccess > SAL_CALL getKeys(  ) throw (::com::sun::star::uno::RuntimeException);
        // XIndexesSupplier
        virtual ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess > SAL_CALL getIndexes(  ) throw (::com::sun::star::uno::RuntimeException);
        // XDataDescriptorFactory
        virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > SAL_CALL createDataDescriptor(  ) throw (::com::sun::star::uno::RuntimeException);
    };
}
#endif // _DBA_CORE_TABLEDECORATOR_HXX_

<commit_msg>new propset<commit_after>/*************************************************************************
 *
 *  $RCSfile: TableDeco.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: oj $ $Date: 2001-04-24 14:41:30 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _DBA_CORE_TABLEDECORATOR_HXX_
#define _DBA_CORE_TABLEDECORATOR_HXX_

#ifndef _COM_SUN_STAR_SDBCX_XCOLUMNSSUPPLIER_HPP_
#include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBCX_XDATADESCRIPTORFACTORY_HPP_
#include <com/sun/star/sdbcx/XDataDescriptorFactory.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBCX_XINDEXESSUPPLIER_HPP_
#include <com/sun/star/sdbcx/XIndexesSupplier.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBCX_XKEYSSUPPLIER_HPP_
#include <com/sun/star/sdbcx/XKeysSupplier.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBCX_XRENAME_HPP_
#include <com/sun/star/sdbcx/XRename.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBCX_XALTERTABLE_HPP_
#include <com/sun/star/sdbcx/XAlterTable.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XSERVICEINFO_HPP_
#include <com/sun/star/lang/XServiceInfo.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBC_XROW_HPP_
#include <com/sun/star/sdbc/XRow.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBC_XCONNECTION_HPP_
#include <com/sun/star/sdbc/XConnection.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XUNOTUNNEL_HPP_
#include <com/sun/star/lang/XUnoTunnel.hpp>
#endif
#ifndef _CPPUHELPER_COMPBASE9_HXX_
#include <cppuhelper/compbase9.hxx>
#endif
#ifndef _CPPUHELPER_IMPLBASE5_HXX_
#include <cppuhelper/implbase5.hxx>
#endif
#ifndef _DBASHARED_APITOOLS_HXX_
#include "apitools.hxx"
#endif
#ifndef _DBA_CORE_DATASETTINGS_HXX_
#include "datasettings.hxx"
#endif
#ifndef _DBA_COREAPI_COLUMN_HXX_
#include <column.hxx>
#endif
#ifndef _CONNECTIVITY_COMMONTOOLS_HXX_
#include <connectivity/CommonTools.hxx>
#endif
#ifndef _CONNECTIVITY_SDBCX_IREFRESHABLE_HXX_
#include <connectivity/sdbcx/IRefreshable.hxx>
#endif
#ifndef _DBA_CORE_CONFIGURATIONFLUSHABLE_HXX_
#include "configurationflushable.hxx"
#endif
#ifndef COMPHELPER_IDPROPERTYARRAYUSAGEHELPER_HXX
#include <comphelper/IdPropArrayHelper.hxx>
#endif

namespace dbaccess
{
    typedef ::cppu::WeakComponentImplHelper9<   ::com::sun::star::sdbcx::XColumnsSupplier,
                                                ::com::sun::star::sdbcx::XKeysSupplier,
                                                ::com::sun::star::container::XNamed,
                                                ::com::sun::star::lang::XServiceInfo,
                                                ::com::sun::star::sdbcx::XDataDescriptorFactory,
                                                ::com::sun::star::sdbcx::XIndexesSupplier,
                                                ::com::sun::star::sdbcx::XRename,
                                                ::com::sun::star::sdbcx::XAlterTable,
                                                ::com::sun::star::lang::XUnoTunnel> OTableDescriptor_BASE;
    //==========================================================================
    //= OTables
    //==========================================================================
    class ODBTableDecorator;
    typedef ::comphelper::OIdPropertyArrayUsageHelper< ODBTableDecorator >  ODBTableDecorator_PROP;

    class ODBTableDecorator :public comphelper::OBaseMutex
                            ,public ODataSettings //ODataSettings_Base
                            ,public OConfigurationFlushable
                            ,public OTableDescriptor_BASE
                            ,public IColumnFactory
                            ,public ::connectivity::sdbcx::IRefreshableColumns
                            ,public ODBTableDecorator_PROP
    {
        void fillPrivileges() const;
    protected:
        ::com::sun::star::uno::Reference< ::com::sun::star::sdbcx::XColumnsSupplier >   m_xTable;
        ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XDatabaseMetaData >   m_xMetaData;
    // <properties>
        sal_Int32                                                                       m_nPrivileges;
    // </properties>
        ::connectivity::sdbcx::OCollection*                                             m_pColumns;

        // IColumnFactory
        virtual OColumn*    createColumn(const ::rtl::OUString& _rName) const;
        virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > createEmptyObject();
        virtual void refreshColumns();

        virtual ::cppu::IPropertyArrayHelper* createArrayHelper(sal_Int32 _nId) const;
        virtual ::cppu::IPropertyArrayHelper & SAL_CALL getInfoHelper();
        // OConfigurationFlushable
        virtual void flush_NoBroadcast_NoCommit();

        // OPropertySetHelper
        virtual sal_Bool SAL_CALL convertFastPropertyValue(
                            ::com::sun::star::uno::Any & rConvertedValue,
                            ::com::sun::star::uno::Any & rOldValue,
                            sal_Int32 nHandle,
                            const ::com::sun::star::uno::Any& rValue )
                                throw (::com::sun::star::lang::IllegalArgumentException);
        virtual void SAL_CALL getFastPropertyValue(::com::sun::star::uno::Any& rValue, sal_Int32 nHandle) const;
        virtual void SAL_CALL setFastPropertyValue_NoBroadcast(
                                sal_Int32 nHandle,
                                const ::com::sun::star::uno::Any& rValue
                                                 )
                                                 throw (::com::sun::star::uno::Exception);
    public:
        /** constructs a wrapper supporting the com.sun.star.sdb.Table service.

            @param          _rxConn         the connection the table belongs to
            @param          _rxTable        the table from the driver can be null
        */
        ODBTableDecorator(const OConfigurationNode& _rTableConfig,
                const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XDatabaseMetaData >& _rxConn,
                const ::com::sun::star::uno::Reference< ::com::sun::star::sdbcx::XColumnsSupplier >& _rxTable)
            throw(::com::sun::star::sdbc::SQLException);

        ODBTableDecorator(  const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XDatabaseMetaData >& _rxConn,
                    const ::com::sun::star::uno::Reference< ::com::sun::star::sdbcx::XColumnsSupplier >& _rxNewTable)
            throw(::com::sun::star::sdbc::SQLException);
        virtual ~ODBTableDecorator();

        // ODescriptor
        virtual void construct();

        //XInterface
        virtual ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException);
        //XTypeProvider
        virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL getTypes(  ) throw(::com::sun::star::uno::RuntimeException);
        virtual ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId() throw (::com::sun::star::uno::RuntimeException);

    // OComponentHelper
        virtual void SAL_CALL disposing(void);

    // ::com::sun::star::lang::XServiceInfo
        DECLARE_SERVICE_INFO();
        // XInterface
        DECLARE_CTY_DEFAULTS(OTableDescriptor_BASE);

        // XPropertySet
        virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo(  ) throw(::com::sun::star::uno::RuntimeException);
    // ::com::sun::star::sdbcx::XRename,
        virtual void SAL_CALL rename( const ::rtl::OUString& _rNewName ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::container::ElementExistException, ::com::sun::star::uno::RuntimeException);

    // ::com::sun::star::sdbcx::XAlterTable,
        virtual void SAL_CALL alterColumnByName( const ::rtl::OUString& _rName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& _rxDescriptor ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::container::NoSuchElementException, ::com::sun::star::uno::RuntimeException);
        virtual void SAL_CALL alterColumnByIndex( sal_Int32 _nIndex, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& _rxDescriptor ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);

        // XNamed
        virtual ::rtl::OUString SAL_CALL getName() throw(::com::sun::star::uno::RuntimeException);
        virtual void SAL_CALL setName( const ::rtl::OUString& aName ) throw (::com::sun::star::uno::RuntimeException)
        {
        }
        // com::sun::star::lang::XUnoTunnel
        virtual sal_Int64 SAL_CALL getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& aIdentifier ) throw(::com::sun::star::uno::RuntimeException);

        ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XDatabaseMetaData> getMetaData() const { return m_xMetaData; }
        ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection> getConnection() const { return m_xMetaData->getConnection(); }

        // XColumnsSupplier
        virtual ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess > SAL_CALL getColumns(  ) throw (::com::sun::star::uno::RuntimeException);
        // XKeysSupplier
        virtual ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexAccess > SAL_CALL getKeys(  ) throw (::com::sun::star::uno::RuntimeException);
        // XIndexesSupplier
        virtual ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess > SAL_CALL getIndexes(  ) throw (::com::sun::star::uno::RuntimeException);
        // XDataDescriptorFactory
        virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > SAL_CALL createDataDescriptor(  ) throw (::com::sun::star::uno::RuntimeException);
    };
}
#endif // _DBA_CORE_TABLEDECORATOR_HXX_

<|endoftext|>


<commit_before><commit_msg>Forget V8Object before removing it from g_live_objects set can cause a crash on Android:<commit_after><|endoftext|>