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 #include <UT/UT_DSOVersion.h>
00028 #include <OP/OP_OperatorTable.h>
00029
00030 #include <PRM/PRM_Include.h>
00031 #include <PRM/PRM_Parm.h>
00032
00033 #include <SYS/SYS_Math.h>
00034
00035 #include <TIL/TIL_Region.h>
00036 #include <TIL/TIL_Tile.h>
00037 #include <TIL/TIL_TileList.h>
00038
00039 #include <PXL/PXL_Pixel.h>
00040 #include <RU/RU_Algorithm.h>
00041 #include <COP2/COP2_CookAreaInfo.h>
00042
00043 #include "COP2_SampleFilter.h"
00044
00045 using namespace HDK_Sample;
00046
00047 COP_MASK_SWITCHER(4, "HDK Sample Filter");
00048
00049 static PRM_Name names[] =
00050 {
00051 PRM_Name("left", "Left Enhance"),
00052 PRM_Name("right", "Right Enhance"),
00053 PRM_Name("top", "Top Enhance"),
00054 PRM_Name("bottom", "Bottom Enhance"),
00055 };
00056
00057
00058 PRM_Template
00059 COP2_SampleFilter::myTemplateList[] =
00060 {
00061 PRM_Template(PRM_SWITCHER, 3, &PRMswitcherName, switcher),
00062
00063 PRM_Template(PRM_FLT_J, TOOL_PARM, 1, &names[0],PRMzeroDefaults),
00064 PRM_Template(PRM_FLT_J, TOOL_PARM, 1, &names[1],PRMzeroDefaults),
00065 PRM_Template(PRM_FLT_J, TOOL_PARM, 1, &names[2],PRMzeroDefaults),
00066 PRM_Template(PRM_FLT_J, TOOL_PARM, 1, &names[3],PRMzeroDefaults),
00067
00068 PRM_Template(),
00069 };
00070
00071 OP_TemplatePair COP2_SampleFilter::myTemplatePair( COP2_SampleFilter::myTemplateList,
00072 &COP2_MaskOp::myTemplatePair);
00073
00074 OP_VariablePair COP2_SampleFilter::myVariablePair( 0,&COP2_Node::myVariablePair );
00075
00076 const char * COP2_SampleFilter::myInputLabels[] =
00077 {
00078 "Image to Enhance",
00079 "Mask Input",
00080 0
00081 };
00082
00083
00084 OP_Node *
00085 COP2_SampleFilter::myConstructor(OP_Network *net,
00086 const char *name,
00087 OP_Operator *op)
00088 {
00089 return new COP2_SampleFilter(net, name, op);
00090 }
00091
00092 COP2_SampleFilter::COP2_SampleFilter(OP_Network *parent,
00093 const char *name,
00094 OP_Operator *entry)
00095 : COP2_MaskOp(parent, name, entry)
00096 {}
00097
00098 COP2_SampleFilter::~COP2_SampleFilter()
00099 {}
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109 COP2_ContextData *
00110 COP2_SampleFilter::newContextData(const TIL_Plane *, int ,
00111 float t, int xres, int yres,
00112 int , int)
00113 {
00114
00115
00116 cop2_SampleFilterContext *data = new cop2_SampleFilterContext;
00117 float scx, scy;
00118
00119
00120 int index = mySequence.getImageIndex(t);
00121 float effect = getFrameScopeEffect(index);
00122
00123
00124
00125 getScaleFactors(xres,yres, scx, scy);
00126 effect *= SYSmin(scx,scy);
00127
00128 data->myLeft = LEFT(t) * effect;
00129 data->myRight = RIGHT(t) * effect;
00130 data->myTop = TOP(t) * effect;
00131 data->myBottom = BOTTOM(t) * effect;
00132
00133 data->myKernel = new float[9];
00134
00135
00136
00137
00138
00139 data->myKernel[0] = -data->myLeft -data->myTop;
00140 data->myKernel[1] = -data->myTop;
00141 data->myKernel[2] = -data->myRight -data->myTop;
00142
00143 data->myKernel[3] = -data->myLeft;
00144 data->myKernel[5] = -data->myRight;
00145
00146 data->myKernel[6] = -data->myLeft -data->myBottom;
00147 data->myKernel[7] = -data->myBottom;
00148 data->myKernel[8] = -data->myRight -data->myBottom;
00149
00150
00151 data->myKernel[4] = 1.0f + 3.0f * (data->myLeft + data->myRight +
00152 data->myTop + data->myBottom);
00153 return data;
00154 };
00155
00156
00157 void
00158 COP2_SampleFilter::computeImageBounds(COP2_Context &context)
00159 {
00160 int x1,y1,x2,y2;
00161
00162
00163
00164 COP2_MaskOp::computeImageBounds(context);
00165
00166
00167
00168 context.getImageBounds(x1,y1,x2,y2);
00169 context.setImageBounds(x1-1, y1-1, x2+1, y2+1);
00170 }
00171
00172
00173 void
00174 COP2_SampleFilter::getInputDependenciesForOutputArea(
00175 COP2_CookAreaInfo &output_area,
00176 const COP2_CookAreaList &input_areas,
00177 COP2_CookAreaList &needed_areas)
00178 {
00179
00180 COP2_MaskOp::getInputDependenciesForOutputArea(output_area, input_areas,
00181 needed_areas);
00182
00183
00184 if (getBypass())
00185 return;
00186
00187
00188 COP2_CookAreaInfo *inarea =
00189 makeOutputAreaDependOnMyPlane(0, output_area,input_areas,needed_areas);
00190
00191
00192 if(inarea)
00193 inarea->expandNeededArea(1, 1, 1, 1);
00194 }
00195
00196
00197
00198
00199
00200 const char *
00201 COP2_SampleFilter::getOperationInfo()
00202 {
00203 return "This operation enhances individual edges.";
00204 }
00205
00206 namespace HDK_Sample {
00207
00208
00209 class cop2_EdgeEnhance : public RU_Algorithm
00210 {
00211 public:
00212 cop2_EdgeEnhance(const float *kernel) : myKernel(kernel) {}
00213 virtual ~cop2_EdgeEnhance() {}
00214
00215 DECLARE_FILTER_OP(cop2_EdgeEnhanceOp);
00216
00217 const float *myKernel;
00218 };
00219
00220
00221 template<class Type,int fast> class cop2_EdgeEnhanceOp
00222 : public RU_FilterOp<Type,fast>
00223 {
00224 public:
00225 cop2_EdgeEnhanceOp(RU_Algorithm *alg)
00226 : RU_FilterOp<Type,fast>(alg)
00227 { ; }
00228 virtual ~cop2_EdgeEnhanceOp() {;}
00229
00230 virtual int filter(TIL_TileList *output,
00231 const TIL_Region *input, float t,
00232 int thread=-1, void *data=0);
00233 };
00234
00235 IMPLEMENT_FILTER_OP(cop2_EdgeEnhance, cop2_EdgeEnhanceOp);
00236
00237
00238 template<class Type,int fast> int
00239 cop2_EdgeEnhanceOp<Type,fast>::filter(TIL_TileList *output,
00240 const TIL_Region *input, float t,
00241 int thread, void *data)
00242 {
00243 PXL_Pixel<Type,fast> pixel(output->myBlack, output->myWhite);
00244 cop2_EdgeEnhance *parm =
00245 static_cast<cop2_EdgeEnhance *>(RU_FilterOp<Type,fast>::myAlg);
00246 const float *kernel = parm->myKernel;
00247 TIL_Tile *itr=0;
00248 const Type *source_data, *iscan1, *iscan2, *iscan3;
00249 Type *dest_data, *scan;
00250 int ti;
00251 int stride, istride;
00252 float sum;
00253 int x,y;
00254 int w,h;
00255
00256 w = output->myX2 - output->myX1 + 1;
00257 h = output->myY2 - output->myY1 + 1;
00258 stride = w;
00259 istride = w + 2;
00260
00261 FOR_EACH_UNCOOKED_TILE(output, itr, ti)
00262 {
00263 dest_data = (Type *) itr->getImageData();
00264 source_data = (Type *) input->getImageData(ti);
00265
00266
00267 iscan1 = source_data + 1;
00268 iscan2 = iscan1 + istride;
00269 iscan3 = iscan2 + istride;
00270
00271 scan = dest_data;
00272
00273 for(y=0; y<h; y++)
00274 {
00275 for(x=0; x<w; x++)
00276 {
00277 pixel.set(iscan1[x-1]);
00278 sum = (float)pixel * kernel[0];
00279
00280 pixel.set(iscan1[x]);
00281 sum += (float)pixel * kernel[1];
00282
00283 pixel.set(iscan1[x+1]);
00284 sum += (float)pixel * kernel[2];
00285
00286 pixel.set(iscan2[x-1]);
00287 sum += (float)pixel * kernel[3];
00288
00289 pixel.set(iscan2[x]);
00290 sum += (float)pixel * kernel[4];
00291
00292 pixel.set(iscan2[x+1]);
00293 sum += (float)pixel * kernel[5];
00294
00295 pixel.set(iscan3[x-1]);
00296 sum += (float)pixel * kernel[6];
00297
00298 pixel.set(iscan3[x]);
00299 sum += (float)pixel * kernel[7];
00300
00301 pixel.set(iscan3[x+1]);
00302 sum += (float)pixel * kernel[8];
00303
00304
00305 pixel = sum;
00306 scan[x] = pixel.getValue();
00307 }
00308
00309 scan += stride;
00310 iscan1 += istride;
00311 iscan2 += istride;
00312 iscan3 += istride;
00313 }
00314 }
00315 return 1;
00316 }
00317
00318 }
00319
00320
00321
00322 OP_ERROR
00323 COP2_SampleFilter::doCookMyTile(COP2_Context &context, TIL_TileList *tiles)
00324 {
00325
00326 cop2_SampleFilterContext *data =
00327 static_cast<cop2_SampleFilterContext *>(context.data());
00328
00329
00330 TIL_Region *in = inputRegion(0, context,
00331 tiles->myX1 -1,
00332 tiles->myY1 -1,
00333 tiles->myX2 +1,
00334 tiles->myY2 +1,
00335 TIL_HOLD);
00336 if(!in)
00337 {
00338 tiles->clearToBlack();
00339 return error();
00340 }
00341
00342
00343 cop2_EdgeEnhance op(data->myKernel);
00344 op.filter(tiles, in, context.myTime, NULL, context.myThreadIndex);
00345
00346 releaseRegion(in);
00347
00348
00349 return error();
00350 }
00351
00352
00353 void
00354 newCop2Operator(OP_OperatorTable *table)
00355 {
00356 table->addOperator(new OP_Operator("hdksamplefilt",
00357 "HDK Sample Filter",
00358 COP2_SampleFilter::myConstructor,
00359 &COP2_SampleFilter::myTemplatePair,
00360 1,
00361 2,
00362 &COP2_SampleFilter::myVariablePair,
00363 0,
00364 COP2_SampleFilter::myInputLabels));
00365 }
00366
00367