00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00032 #include "MTAreaOperator.hpp"
00033 #include <pthread.h>
00034 #include <vector>
00035
00036 using namespace Millie;
00037
00038 struct SharedArea
00039 {
00040 int debut;
00041 Image * dest;
00042 const Image * image;
00043 LocalAreaOperator * localOp;
00044 int nbThreads;
00045 };
00046
00047
00048
00049
00050
00051 static void * areaOperatorMT(void * p_data)
00052 {
00053
00054 SharedArea & shared = *((SharedArea*)p_data);
00055 const Image & image = *shared.image;
00056 Image & dest = *shared.dest;
00057 LocalAreaOperator & localOp = *shared.localOp;
00058
00059 float t;
00060
00061 int leftpadding = localOp.getLeftPadding();
00062 int rightpadding = localOp.getRightPadding();
00063 int toppadding = localOp.getTopPadding();
00064 int bottompadding = localOp.getBottomPadding();
00065 int hauteur = image.getHeight();
00066 int largeur = image.getWidth();
00067
00068
00069 for(int canal=0; canal< image.getNumComponents(); canal++)
00070 for(int j = toppadding + shared.debut; j< hauteur - bottompadding; j+=shared.nbThreads)
00071 {
00072 for(int i = leftpadding; i< largeur - rightpadding; i++)
00073 {
00074 dest.setPixel(i - leftpadding, j - toppadding,
00075 canal, localOp.computeLocalArea(image, i,j, canal));
00076
00077 }
00078 }
00079
00080 return NULL;
00081 }
00082
00083
00084
00085
00086 MTAreaOperator::MTAreaOperator(const LocalAreaOperator & areaOp, int nbthread)
00087 : AreaOperator(areaOp)
00088 {
00089 if(nbthread<1)
00090 throw Millie::IllegalArgument("MTAreaOperator : thread<1");
00091
00092 _nbThread = nbthread;
00093 }
00094
00095 void MTAreaOperator::compute(Image & dest, const Image& in)
00096 {
00097 if(dest.getNumComponents() != in.getNumComponents())
00098 throw IllegalArgument("MTAreaOperator");
00099
00100 int leftpadding = getLeftPadding();
00101 int rightpadding = getRightPadding();
00102 int toppadding = getTopPadding();
00103 int bottompadding = getBottomPadding();
00104 int hauteur = in.getHeight();
00105 int largeur = in.getWidth();
00106
00107 dest.resize(largeur - (rightpadding + leftpadding), hauteur - (toppadding+bottompadding));
00108
00109
00110 std::vector<pthread_t> vectPthread;
00111 std::vector<SharedArea> vectSharedArea;
00112
00113 vectPthread.resize(_nbThread);
00114 vectSharedArea.resize(_nbThread);
00115
00116 for(int i=0; i<_nbThread;i++)
00117 {
00118 SharedArea s;
00119 s.debut = i;
00120 s.dest = &dest;
00121 s.image = ∈
00122 s.localOp = &getLocalAreaOperator();
00123 s.nbThreads = _nbThread;
00124 vectSharedArea[i] = s;
00125 }
00126
00131 for(int i = 0; i<_nbThread;i++)
00132 {
00133 if(pthread_create (&vectPthread[i], NULL, areaOperatorMT, &vectSharedArea[i]) == -1)
00134 throw ThreadCreationFailed("MTAreaOperator : thread creation failed");
00135 }
00136
00141 for(int i = 0; i<_nbThread;i++)
00142 {
00143 if(pthread_join (vectPthread[i], NULL) == -1)
00144 throw RuntimeException("MTAreaOperator : join thread impossibl");
00145 }
00146 }
00147
00148 MTAreaOperator * MTAreaOperator::clone() const
00149 {
00150 return new MTAreaOperator(*this);
00151 }
00152
00153
00154