00001
00002
00003
00004
00005
00006 #ifndef Impala_Visualization_DirImViewer_h
00007 #define Impala_Visualization_DirImViewer_h
00008
00009 #include <time.h>
00010
00011 #include "OglGui/FramesPerSecond.h"
00012 #include "OglGui/DocDimensions.h"
00013 #include "OglGui/DocFlowDrag.h"
00014 #include "Util/DirImageFileNames.h"
00015 #include "Core/Array/ReadFile.h"
00016 #include "Visualization/RgbOglImage.h"
00017
00018 #ifndef NO_RAW
00019 #include "Core/Stream/RgbDataSrcFactory.h"
00020 #endif
00021
00022 namespace Impala {
00023 namespace Visualization {
00024
00025 class DirImViewer : public OglGui::Window,
00026 public OglGui::DocDimensions
00027
00028 {
00029 public:
00030 typedef OglGui::Window Window;
00031 typedef Core::Array::Array2dVec3UInt8 Array2dVec3UInt8;
00032 #ifndef NO_RAW
00033 typedef Core::Stream::RgbDataSrcFactory RgbDataSrcFactory;
00034 typedef Core::Stream::RgbDataSrc RgbDataSrc;
00035 #endif
00036
00037 DirImViewer(int x, int y, int w, int h, int nOnRow=4) :
00038 Window(x,y,w,h)
00039 {
00040 Init(w,h,nOnRow);
00041 }
00042
00043 DirImViewer(Window* parent, int w, int h, int nOnRow=4) :
00044 Window(parent,w,h)
00045 {
00046 Init(w,h,nOnRow);
00047 }
00048
00049 DirImViewer(Window* parent, int x, int y, int w, int h, int nOnRow=4) :
00050 Window(parent,x,y,w,h)
00051 {
00052 Init(w,h,nOnRow);
00053 }
00054
00055 ~DirImViewer()
00056 {
00057 ClearFiles();
00058 }
00059
00060 void OpenDir(strconst dirName)
00061 {
00062 ClearFiles();
00063 mDirName = dirName;
00064 #ifndef NO_RAW
00065 #ifdef REPOSITORY_USED
00066 if (FileNameExt(dirName) == "raw")
00067 {
00068 if (dirName[0] == '/' || dirName[0] == '\\')
00069 OpenSrc(Persistency::RgbDataSrcLocator("file:", "abs", dirName));
00070 else
00071 OpenSrc(Persistency::RgbDataSrcLocator("file:", "dot", dirName));
00072 }
00073 #else
00074 if (FileNameExt(dirName) == "raw")
00075 {
00076 RgbDataSrcFactory& f = RgbDataSrcFactory::Instance();
00077 mRgbDataSrcRaw = f.Construct(dirName, "raw");
00078 }
00079 #endif //REPOSITORY_USED
00080 #endif // NO_RAW
00081 Util::DirImageFileNames(dirName, mFileNames);
00082 HandleDocDimensions(true,true);
00083 }
00084
00085 #if !defined(NO_RAW) && defined(REPOSITORY_USED)
00086 void OpenSrc(const Persistency::RgbDataSrcLocator& loc)
00087 {
00088 ClearFiles();
00089 mDirName = loc.GetName();
00090 RgbDataSrcFactory& f = RgbDataSrcFactory::Instance();
00091 mRgbDataSrcRaw = f.Construct(RgbDataSrcFactory::SRC_RAW, loc);
00092 }
00093 #endif
00094
00095 void NrOfImOnRow(int n) { mFixedCellDims = !(mNrOfImOnRow = n); }
00096 int NrOfImOnRow() { return mNrOfImOnRow; }
00097 void ShowNames(bool mode) { mExtH = (mShowNames = mode) ? 6 : 0; }
00098 bool ShowNames() { return mShowNames; }
00099 void ShowDims(bool mode) { mShowDims = mode; }
00100 bool ShowDims() { return mShowDims; }
00101 int CellWidth() { return mCellW; }
00102 int CellHeight() { return mCellH; }
00103 void PagingExtra(int x) { mPagingExtra = x; }
00104 int PagingExtra() { return mPagingExtra; }
00105
00106 void MaxZoom(double mz) { mMaxZoom = mz; }
00107
00108 int NrOfFiles()
00109 {
00110 #ifndef NO_RAW
00111 if (mRgbDataSrcRaw)
00112 return mRgbDataSrcRaw->LastFrame();
00113 #endif
00114 return mFileNames.size();
00115 }
00116
00117 void FixedCellWidth(int w)
00118 {
00119 if (mFixedCellDims = (w > 20))
00120 mCellH = mExtH + (mCellW = w);
00121 else
00122 mCellH = mExtH + (mCellW = 128);
00123 }
00124
00125 int ClampImIdx(int& idx)
00126 {
00127 if (idx < 0)
00128 idx = 0;
00129 if (idx > NrOfFiles()-1)
00130 idx = NrOfFiles()-1;
00131 return idx;
00132 }
00133
00134 int ClampViewIdx(int& idx)
00135 {
00136 if (idx < 0)
00137 idx = 0;
00138 if (idx > mViews.size()-1)
00139 idx = mViews.size()-1;
00140 return idx;
00141 }
00142
00143 void ClearFiles()
00144 {
00145 #ifndef NO_RAW
00146 if (mRgbDataSrcRaw)
00147 {
00148 delete mRgbDataSrcRaw;
00149 mRgbDataSrcRaw = 0;
00150 }
00151 #endif
00152 unsigned int i;
00153 for (i=0 ; i<mFileNames.size() ; i++)
00154 delete mFileNames[i];
00155 mFileNames.clear();
00156 }
00157
00158 void ClearViews(int start=0, int end=10000)
00159 {
00160 ClampViewIdx(start);
00161 ClampViewIdx(end);
00162 for (int i=start; i<end; i++)
00163 {
00164 viewSys.SetImage(mViews[i], 0);
00165 viewSys.ClearTags(mViews[i], visibleTag);
00166 mViews[i]->UserData1 = (void*)-1;
00167 }
00168 }
00169
00170 int Y2Row(int y)
00171 {
00172 return (mDocY + mDocH - y) / mCellH;
00173 }
00174 int Row2Y(int row)
00175 {
00176 return (mDocY+mDocH-(row+1)*mCellH);
00177 }
00178
00179 int NrRows()
00180 {
00181 return NrOfFiles() / mNrOfImOnRow;
00182 }
00183
00184 int FindFirstVisible()
00185 {
00186 int first = Y2Row(H()) * mNrOfImOnRow;
00187 return ClampImIdx(first);
00188 }
00189 int FindLastVisible()
00190 {
00191 int last = Y2Row(-mCellH) * mNrOfImOnRow;
00192 return ClampImIdx(last);
00193 }
00194
00195 int FindIndexFwd(int imIdx, int start=0)
00196 {
00197 ClampViewIdx(start);
00198 for (int i=start; i<mViews.size(); i++)
00199 {
00200 if (imIdx == (long long) mViews[i]->UserData1)
00201 return i;
00202 }
00203 return -1;
00204 }
00205
00206 int FindIndexBwd(int imIdx, int start=10000)
00207 {
00208 ClampViewIdx(start);
00209 for (int i=start; i>=0; i--)
00210 {
00211 if (imIdx == (long long) mViews[i]->UserData1)
00212 return i;
00213 }
00214 return -1;
00215 }
00216
00217 int FindIndex(int imIdx, int start, bool backward=false)
00218 {
00219 if (backward)
00220 return FindIndexBwd(imIdx, start);
00221 else
00222 return FindIndexFwd(imIdx, start);
00223 }
00224
00225 void HandleDocDimensions(bool resizing=false, bool reset=false)
00226 {
00227 if (!mFixedCellDims)
00228 {
00229 mCellW = W() / mNrOfImOnRow;
00230 mCellH = mCellW + (mShowNames ? mExtH : 0);
00231 }
00232 else if ((mNrOfImOnRow = W() / mCellW)<1)
00233 mNrOfImOnRow = 1;
00234
00235 int docH = (NrOfFiles() / mNrOfImOnRow) * mCellH;
00236
00237 if (resizing && mOldStartIm != -1)
00238 {
00239 int row = mOldStartIm / mNrOfImOnRow;
00240 mDocY = H() - (NrRows() - row) * mCellH;
00241 }
00242 if (mDocY < (-docH+H()))
00243 mDocY = -docH+H();
00244 if (reset)
00245 SetDocDimensions(0,-docH+H(),W(), docH);
00246 else
00247 SetDocDimensions(mDocX, mDocY, W(), docH);
00248 }
00249
00250 void HandleViewText(OGLVIEW* oglView)
00251 {
00252 if (!(mShowNames || mShowDims))
00253 return;
00254
00255 OGLIMAGE* oglIm = oglView->im;
00256 int txtX = oglView->x;
00257 int txtY = oglView->y-14;
00258 std::string txt = "";
00259
00260 if (mShowNames)
00261 {
00262 int userData1 = (long long)oglView->UserData1;
00263 #ifndef NO_RAW
00264 if (mRgbDataSrcRaw)
00265 txt = "im " + MakeString(userData1) + " ";
00266 else
00267 #endif
00268 txt = *mFileNames[userData1] + " ";
00269 }
00270 if (mShowDims)
00271 {
00272 char buf[20];
00273 sprintf(buf, "[%dx%d]", oglIm->w, oglIm->h);
00274 txt += buf;
00275 }
00276 oglSys.StartScissor(mOglWnd,txtX,txtY-4,oglView->w,20);
00277 oglSys.PosColPrintf(mOglWnd,txtX,txtY,GetForeground(),"%s",txt.c_str());
00278 oglSys.EndScissor();
00279 }
00280
00281 void HandleViewZoom(OGLVIEW* oglView)
00282 {
00283 OGLIMAGE* oglIm = oglView->im;
00284 float zoomX, zoomY;
00285
00286 if (oglIm->w >= oglIm->h)
00287 zoomY = zoomX = (oglView->w)/(float)oglIm->w;
00288 else
00289 zoomX = zoomY = (oglView->h)/(float)oglIm->h;
00290 if (zoomX > mMaxZoom)
00291 zoomX = zoomY = mMaxZoom;
00292 viewSys.SetZoom(oglView, zoomX, zoomY);
00293 }
00294
00295 virtual void HandleViewDecoration(OGLVIEW* view)
00296 {
00297 SetSolidLineColor(oglLIGHTGREY);
00298 DrawRectangle(view->x-2, view->y-2, view->w+4, view->h+4);
00299 }
00300
00301 void HandleViewSettings(int vIdx)
00302 {
00303 OGLVIEW* oglView;
00304 if (vIdx<0 || vIdx>mViews.size() || !(oglView=mViews[vIdx]))
00305 return;
00306 if (!mViews[vIdx]->im)
00307 return;
00308 HandleViewZoom(oglView);
00309 HandleViewText(oglView);
00310 HandleViewDecoration(oglView);
00311 }
00312
00313 void ViewCreateImage(int dstIdx, int imIdx)
00314 {
00315 Array2dVec3UInt8* ar = 0;
00316 #ifndef NO_RAW
00317 if (mRgbDataSrcRaw)
00318 {
00319 mRgbDataSrcRaw->GotoFrame(imIdx);
00320 int imW = mRgbDataSrcRaw->FrameWidth();
00321 int imH = mRgbDataSrcRaw->FrameHeight();
00322 ar = new Array2dVec3UInt8(imW, imH, 0, 0, 0, false);
00323 memcpy( (void *) ar->CPB(0, 0), mRgbDataSrcRaw->DataPtr(), imW*imH*3 );
00324 }
00325 else
00326 #endif
00327 {
00328 std::string fName = mDirName + "/" + *mFileNames[imIdx];
00329 #ifndef REPOSITORY_USED // Here comes the deprecated stuff
00330 Core::Array::ReadFile(ar, fName, &Util::Database::GetInstance());
00331 #else // REPOSITORY_USED
00332
00333 Persistency::FileLocator loc(fName);
00334 typedef Persistency::RepositoryInFileSystem FS;
00335 Persistency::File f = FS::GetInstance().GetFile(loc, false, false);
00336 Core::Array::ReadFile(ar, f);
00337 #endif // REPOSITORY_USED
00338 if (ar == 0)
00339 {
00340 ILOG_WARN("Could not read file: " << fName);
00341 }
00342 }
00343 if (ar != 0)
00344 {
00345 OGLIMAGE* oglIm = RgbOglImage::OglImage(ar);
00346 viewSys.SetImage(mViews[dstIdx],oglIm);
00347 ReleaseOglImage(oglIm);
00348 } else {
00349 ILOG_WARN("array = 0, image not loaded.");
00350 viewSys.SetImage(mViews[dstIdx], 0);
00351 }
00352 mViews[dstIdx]->UserData1 = (void *) imIdx;
00353 }
00354
00355 void CopyImageFromView(int dstIdx, int srcIdx, int imIdx)
00356 {
00357 viewSys.SetImage(mViews[dstIdx], mViews[srcIdx]->im);
00358 mViews[dstIdx]->UserData1 = (void *) imIdx;
00359 }
00360
00361 bool ViewNewPositionNeedsIm(int vIdx, int imIdx)
00362 {
00363 int row = imIdx / mNrOfImOnRow;
00364 int x = (imIdx%mNrOfImOnRow) * mCellW + 4;
00365 int y = Row2Y(row) + 12 + mExtH;
00366 int w = mCellW - 8;
00367 int h = mCellH - (18+mExtH);
00368
00369 viewSys.SetDimensions(mViews[vIdx], x, y, w, h);
00370 viewSys.SetTags(mViews[vIdx], visibleTag);
00371 return ((long long) mViews[vIdx]->UserData1) != imIdx;
00372 }
00373
00374 virtual void ReshapeFunc(int w, int h)
00375 {
00376 Window::ReshapeFunc(w,h);
00377 HandleDocDimensions(true,false);
00378 }
00379
00380 void HandleView(int vIdx, int imIdx, bool bwd)
00381 {
00382 if (vIdx < 0 || vIdx > mViews.size()-1)
00383 return;
00384 if (ViewNewPositionNeedsIm(vIdx,imIdx))
00385 {
00386 int foundIdx;
00387 if ((foundIdx = FindIndex(imIdx,vIdx,bwd))!=-1)
00388 CopyImageFromView(vIdx,foundIdx,imIdx);
00389 else
00390 ViewCreateImage(vIdx,imIdx);
00391 }
00392 HandleViewSettings(vIdx);
00393 }
00394
00395 virtual void DisplayFunc()
00396 {
00397 int cellH = CellHeight();
00398 int h = H();
00399 int dif = (cellH > h) ? h-cellH : h % cellH;
00400
00401 mFlowDragger.SetFlowPageExtra(dif-mPagingExtra);
00402 mFlowDragger.FlowDragDisplay();
00403 OGC myOGC;
00404 OGCSave(&myOGC);
00405 int first = FindFirstVisible();
00406 int last = FindLastVisible();
00407 int range = last - first + 1;
00408 int i, vIdx;
00409 if (mOldStartIm <= first)
00410 {
00411 for (i=first, vIdx=-1; i<=last; i++)
00412 HandleView(++vIdx,i,false);
00413 ClearViews(vIdx+1);
00414 }
00415 else
00416 {
00417 for (i=last, vIdx=range; i>=first; i--)
00418 HandleView(--vIdx, i, true);
00419 ClearViews(range);
00420 }
00421 mOldStartIm = first;
00422 OGCRestore(&myOGC);
00423 Window::DisplayFunc();
00424 }
00425
00426 virtual void KeyboardFunc(int c, int state)
00427 {
00428 int oldDocY = mDocY;
00429 mFlowDragger.KeyboardFunc(c,state);
00430
00431 if (c == '~')
00432 mFixedCellDims = !mFixedCellDims;
00433
00434 Window::KeyboardFunc(c, state);
00435
00436 if (oldDocY != mDocY)
00437 return;
00438 if (c==oglPAGEDOWN)
00439 mDocY += H();
00440 if (c==oglPAGEUP)
00441 mDocY -= H();
00442 if (c==oglUP)
00443 mDocY += 10;
00444 if (c==oglDOWN)
00445 mDocY -= 10;
00446 }
00447
00448 virtual void MouseFunc(int msg, int but, int state, int x, int y)
00449 {
00450 mFlowDragger.MouseFunc(msg,but,state,x,y);
00451 Window::MouseFunc(msg,but,state,x,y);
00452 }
00453
00454 private:
00455
00456 void Init(int w, int h, int nOnRow)
00457 {
00458 mFlowDragger.SetDocWnd(this,this);
00459 SetDocDimensions(0,0,w,h);
00460 ShowNames(true);
00461 ShowDims(true);
00462 FixedCellWidth(132);
00463 NrOfImOnRow(nOnRow);
00464 ShowNames(true);
00465 ShowDims(true);
00466 mOldStartIm = -1;
00467 mPagingExtra = 1;
00468 mMaxZoom = 2;
00469 for (int i=0; i<1000; i++)
00470 {
00471 OGLVIEW* view = viewSys.View2D(mOglWnd,0,0,0,128,128);
00472 viewSys.SetTags(view, FlexViewTags);
00473 viewSys.ClearTags(view, visibleTag|showBorderTag|showBgTag|selectableTag);
00474
00475 viewSys.SetColor(view, OGL_BG, oglTrLIGHTGREY);
00476 view->UserData1 = (void *) -1;
00477 mViews.push_back(view);
00478 }
00479 #ifndef NO_RAW
00480 mRgbDataSrcRaw = 0;
00481 #endif
00482 }
00483
00484 std::string mDirName;
00485 std::vector<std::string*> mFileNames;
00486 std::vector<OGLVIEW*> mViews;
00487 #ifndef NO_RAW
00488 RgbDataSrc* mRgbDataSrcRaw;
00489 #endif
00490
00491 bool mFixedCellDims;
00492 bool mShowNames;
00493 bool mShowDims;
00494 int mNrOfImOnRow;
00495 int mCellW;
00496 int mCellH;
00497 int mExtH;
00498
00499 int mOldStartIm;
00500 int mPagingExtra;
00501
00502 double mMaxZoom;
00503 OglGui::DocFlowDrag mFlowDragger;
00504
00505 ILOG_VAR_DEC;
00506 };
00507
00508 ILOG_VAR_INIT(DirImViewer, Visualization);
00509
00510 }
00511 }
00512 #endif