Image.cpp

Go to the documentation of this file.
00001 /*
00002 *        This file contains classes that represents image returned from camera.
00003 *
00004 *       Author:
00005 *                       Tomas Mrkvicka
00006 *                       xmrkvi03@stud.fit.vutbr.cz
00007 *
00008 */
00009 
00010 #include <cassert>
00011 
00012 #include "pipeline/Image.h"
00013 #include "pipeline/ImagePixelFormats.h"
00014 
00015 ////////////////////////////////////////////////////////////////////////////////
00016 ////////////////////////////////////////////////////////////////////////////////
00017 ////////////////////////////////////////////////////////////////////////////////
00018 // TImageARGB
00019 
00020 /** Vrati velikost jednoho pixelu v bajtech
00021 */
00022 DWORD TImageARGB::GetPixelSize(void) const
00023 {
00024         return 4;
00025 }
00026 //OK 2007-08-25 15:07:14 B04-315B\Tom
00027 
00028 /** Vrati sirku v pixelech.
00029 */
00030 DWORD TImageARGB::GetWidth(void) const
00031 {
00032         return m_width;
00033 }
00034 //OK 2007-08-25 15:07:17 B04-315B\Tom
00035 
00036 /** Vrati vysku v pixelech.
00037 */
00038 DWORD TImageARGB::GetHeight(void) const
00039 {
00040         return m_height;
00041 }
00042 //OK 2007-08-25 15:07:19 B04-315B\Tom
00043 
00044 /** Vrati pocet bajtu mezi pixely na sousednich radcich.
00045 */
00046 DWORD TImageARGB::GetPitch(void) const
00047 {
00048         return m_width * 4;
00049 }
00050 //OK 2007-08-25 15:07:22 B04-315B\Tom
00051 
00052 /** Vrati velikost obrazovych dat v bajtech.
00053 */
00054 DWORD TImageARGB::GetDataSize(void) const
00055 {
00056         return m_width * m_height * 4;
00057 }
00058 //OK 2007-08-25 15:07:25 B04-315B\Tom
00059 
00060 /** Vrati obrazova data.
00061 */
00062 const void*     TImageARGB::GetData(void) const
00063 {
00064         return m_data;
00065 }
00066 //OK 2007-08-25 15:07:28 B04-315B\Tom
00067 
00068 /** Virtualni soukromy destruktor.
00069 */
00070 TImageARGB::~TImageARGB(void)
00071 {
00072         delete [] m_data;
00073         m_data = NULL;          // can be removed
00074 }
00075 //OK 2007-08-25 15:07:30 B04-315B\Tom
00076 
00077 /** Soukromy konstruktor.
00078 *
00079 *       \param  width   [in] sirka obrazku v pixelech
00080 *       \param  height  [in] vyska obrazku v pixelech
00081 */
00082 TImageARGB::TImageARGB(DWORD width, DWORD height)
00083 {
00084         m_width         = width;
00085         m_height        = height;
00086 
00087         m_data = new unsigned char[ width * height * 4];
00088 }
00089 //OK 2007-08-25 15:07:33 B04-315B\Tom
00090 
00091 /** Metoda vytvori obraz z 8-bitoveho formatu ve stupnich sedi.
00092 *
00093 *       \warning        Oba obrazy musi mit stejne rozmery!
00094 *       Pokud ne pak metoda ponecha obraz nezmeneny.
00095 *
00096 *       \param  image   [in] obraz ve stupnich
00097 */
00098 void TImageARGB::FromGray( const TImageGray * image )
00099 {
00100         if ( 
00101                 this->GetWidth()        != image->GetWidth() ||
00102                 this->GetHeight()       != image->GetHeight()
00103         )
00104         {
00105                 //rozdilna velikost obrazu
00106                 return;
00107         }
00108 
00109         const unsigned char * data      = (const unsigned char*)image->GetData();
00110         const DWORD pixelCount          = this->GetWidth() * this->GetHeight();
00111 
00112         for ( DWORD i = 0 ; i < pixelCount ; i++ ) //pro vsechny pixely
00113         {
00114                 unsigned char * pixel   = (unsigned char*)(&((DWORD*)m_data)[i]);
00115                 
00116                 pixel[0]        = data[i];
00117                 pixel[1]        = data[i];
00118                 pixel[2]        = data[i];
00119                 pixel[3]        = 255;          
00120         }
00121 }
00122 //OK 2007-08-25 15:09:19 B04-315B\Tom
00123 
00124 /** Metoda vytvori obraz z barevneho 24-bitoveho obrazu.
00125 *
00126 *       \note   Alpha kanal je nastaven na 255.
00127 *
00128 *       \warning        Oba obrazy musi mit stejne rozmery!
00129 *       Pokud ne pak metoda ponecha obraz nezmeneny.
00130 *
00131 *       \param  image   [in] obraz ve stupnich
00132 */
00133 void TImageARGB::FromRGB( const TImageRGB * image )
00134 {
00135         if ( 
00136                 this->GetWidth()        != image->GetWidth() ||
00137                 this->GetHeight()       != image->GetHeight()
00138         )
00139         {
00140                 //rozdilna velikost obrazu
00141                 return;
00142         }
00143 
00144         const unsigned char * src       = (const unsigned char*)image->GetData();       
00145         const DWORD byteCount           = this->GetDataSize();
00146 
00147         DWORD offsetSrc = 0;
00148         DWORD offsetDst = 0;
00149 
00150         while ( offsetDst < byteCount ) //pro vsechny pixely
00151         {
00152                 m_data[ offsetDst++ ]   = src[ offsetSrc++ ];   // B
00153                 m_data[ offsetDst++ ]   = src[ offsetSrc++ ];   // G
00154                 m_data[ offsetDst++ ]   = src[ offsetSrc++ ];   // R
00155                 m_data[ offsetDst++ ]   = 255;                                  // A
00156         }
00157 }
00158 //OK 2007-09-04 13:41:21 B04-315B\Tom
00159 
00160 /** Metoda zkopiruje zadany vyrez z poskytnuteho obrazku typu ARGB a zkopiruje jej
00161 *       do leveho horniho rohu tohoto obrazu.
00162 *
00163 *       \warning        Velikost vyrezu kopirovaneho obrazu nesmi byt vetsi nez velikost tohoto
00164 *       obrazu. Pokud ano pak metoda neprovede nic. Zaroven musi byt cely vyrez obsazen v poskytnutem
00165 *       obraze.
00166 *
00167 *       \param  src             [in] zdrojovy obraz
00168 *       \param  x               [in] x-souradnice leveho horniho rohu vyrezu
00169 *       \param  y               [in] y-souradnice leveho horniho rohu vyrezu
00170 *       \param  width   [in] sirka vyrezu v pixelech
00171 *       \param  height  [in] vyska vyrezu v pixelech
00172 */
00173 void TImageARGB::CopyFrom( const TImageARGB * src, DWORD x, DWORD y, DWORD width, DWORD height)
00174 {       
00175         if (
00176                 ( width > 0 ) && ( height > 0 ) &&                      // vyrez musi mit platnou velikost
00177                 src->IsRectInside( x, y, width, height ) &&     //zdrojovy vyrez musi byt uvnitr zdrojoveho obrazku
00178                 width <= m_width &&             // cely vyrez lze zkopirovat do tohoto obrazku
00179                 height <= m_height
00180         )
00181         {
00182                 //zkopirujeme data radek po radku
00183 
00184                 const DWORD * tmpDataSrc = (DWORD*) src->m_data;
00185                 DWORD * tmpDataDst = (DWORD*) this->m_data;
00186 
00187                 for ( DWORD dy = 0 ; dy < height ; dy++ )
00188                 {
00189                         const DWORD * startSrc  = &tmpDataSrc[ (y + dy) * src->m_width + x ];
00190                         DWORD * startDst                = &tmpDataDst[ dy * m_width ];
00191 
00192                         memcpy( startDst, startSrc, sizeof( DWORD ) * width );
00193                 }
00194         }
00195         else
00196         {
00197                 //chybne rozmery vyrezu - nic se nekopiruje
00198         }
00199 }
00200 //OK 2007-08-26 17:09:54 B04-315B\Tom
00201 
00202 // TImageARGB
00203 ////////////////////////////////////////////////////////////////////////////////
00204 ////////////////////////////////////////////////////////////////////////////////
00205 ////////////////////////////////////////////////////////////////////////////////
00206 // TImageRGB
00207 
00208 /** Vrati velikost jednoho pixelu v bajtech
00209 */
00210 DWORD TImageRGB::GetPixelSize(void) const
00211 {
00212         return 3;
00213 }
00214 //OK 2007-09-04 12:11:44 B04-315B\Tom
00215 
00216 /** Vrati sirku v pixelech.
00217 */
00218 DWORD TImageRGB::GetWidth(void) const
00219 {
00220         return m_width;
00221 }
00222 //OK 2007-09-04 12:11:54 B04-315B\Tom
00223 
00224 /** Vrati vysku v pixelech.
00225 */
00226 DWORD TImageRGB::GetHeight(void) const
00227 {
00228         return m_height;
00229 }
00230 //OK 2007-09-04 12:12:20 B04-315B\Tom
00231 
00232 /** Vrati pocet bajtu mezi pixely na sousednich radcich.
00233 */
00234 DWORD TImageRGB::GetPitch(void) const
00235 {
00236         return m_width * 3;
00237 }
00238 //OK 2007-09-04 12:12:38 B04-315B\Tom
00239 
00240 /** Vrati velikost obrazovych dat v bajtech.
00241 */
00242 DWORD TImageRGB::GetDataSize(void) const
00243 {
00244         return m_width * m_height * 3;
00245 }
00246 //OK 2007-09-04 12:12:51 B04-315B\Tom
00247 
00248 /** Vrati obrazova data.
00249 */
00250 const void*     TImageRGB::GetData(void) const
00251 {
00252         return m_data;
00253 }
00254 //OK 2007-09-04 12:13:04 B04-315B\Tom
00255 
00256 /** Virtualni soukromy destruktor.
00257 */
00258 TImageRGB::~TImageRGB(void)
00259 {
00260         delete [] m_data;
00261         m_data = NULL;          // can be removed
00262 }
00263 //OK 2007-09-04 12:13:16 B04-315B\Tom
00264 
00265 /** Soukromy konstruktor.
00266 *
00267 *       \param  width   [in] sirka obrazku v pixelech
00268 *       \param  height  [in] vyska obrazku v pixelech
00269 */
00270 TImageRGB::TImageRGB(DWORD width, DWORD height)
00271 {
00272         m_width         = width;
00273         m_height        = height;
00274 
00275         m_data = new unsigned char[ width * height * 3];
00276 }
00277 //OK 2007-09-04 12:13:33 B04-315B\Tom
00278 
00279 /** Metoda vytvori obraz z 8-bitoveho formatu ve stupnich sedi.
00280 *
00281 *       \warning        Oba obrazy musi mit stejne rozmery!
00282 *       Pokud ne pak metoda ponecha obraz nezmeneny.
00283 *
00284 *       \param  image   [in] obraz ve stupnich sedi
00285 */
00286 void TImageRGB::FromGray( const TImageGray * image )
00287 {
00288         if ( 
00289                 this->GetWidth()        != image->GetWidth() ||
00290                 this->GetHeight()       != image->GetHeight()
00291         )
00292         {
00293                 //rozdilna velikost obrazu
00294                 return;
00295         }
00296 
00297         const unsigned char * data      = (const unsigned char*)image->GetData();
00298         const DWORD pixelCount          = this->GetWidth() * this->GetHeight(); 
00299 
00300         DWORD offsetDst = 0;
00301 
00302         for ( DWORD i = 0 ; i < pixelCount ; i++ ) //pro vsechny pixely
00303         {                       
00304                 m_data[ offsetDst++ ]   = data[i];
00305                 m_data[ offsetDst++ ]   = data[i];
00306                 m_data[ offsetDst++ ]   = data[i];                              
00307         }
00308 }
00309 //OK 2007-09-04 13:15:46 B04-315B\Tom
00310 
00311 /** Metoda vytvori obraz z 32-bitoveho ARGB formatu.
00312 *
00313 *       \warning        Oba obrazy musi mit stejne rozmery!
00314 *       Pokud ne pak metoda ponecha obraz nezmeneny.
00315 *
00316 *       \param  image   [in] barevny obraz ve formatu ARGB
00317 */
00318 void TImageRGB::FromARGB( const TImageARGB * image )
00319 {
00320         if ( 
00321                 this->GetWidth()        != image->GetWidth() ||
00322                 this->GetHeight()       != image->GetHeight()
00323         )
00324         {
00325                 //rozdilna velikost obrazu
00326                 return;
00327         }
00328 
00329         const unsigned char * src       = (const unsigned char*)image->GetData();       
00330         const DWORD byteCount           = this->GetDataSize();
00331 
00332         DWORD offsetSrc = 0;
00333         DWORD offsetDst = 0;
00334 
00335         while ( offsetDst < byteCount ) //pro vsechny pixely
00336         {
00337                 m_data[ offsetDst++ ]   = src[ offsetSrc++ ];   // B
00338                 m_data[ offsetDst++ ]   = src[ offsetSrc++ ];   // G
00339                 m_data[ offsetDst++ ]   = src[ offsetSrc++ ];   // R
00340                 
00341                 offsetSrc++;
00342         }
00343 }
00344 //OK 2007-09-04 13:49:38 B04-315B\Tom
00345 
00346 /** Metoda zkopiruje zadany vyrez z poskytnuteho obrazku typu ARGB a zkopiruje jej
00347 *       do leveho horniho rohu tohoto obrazu.
00348 *
00349 *       \warning        Velikost vyrezu kopirovaneho obrazu nesmi byt vetsi nez velikost tohoto
00350 *       obrazu. Pokud ano pak metoda neprovede nic. Zaroven musi byt cely vyrez obsazen v poskytnutem
00351 *       obraze.
00352 *
00353 *       \param  src             [in] zdrojovy obraz
00354 *       \param  x               [in] x-souradnice leveho horniho rohu vyrezu
00355 *       \param  y               [in] y-souradnice leveho horniho rohu vyrezu
00356 *       \param  width   [in] sirka vyrezu v pixelech
00357 *       \param  height  [in] vyska vyrezu v pixelech
00358 */
00359 void TImageRGB::CopyFrom( const TImageRGB * src, DWORD x, DWORD y, DWORD width, DWORD height)
00360 {       
00361         if (
00362                 ( width > 0 ) && ( height > 0 ) &&                      // vyrez musi mit platnou velikost
00363                 src->IsRectInside( x, y, width, height ) &&     //zdrojovy vyrez musi byt uvnitr zdrojoveho obrazku
00364                 width <= m_width &&             // cely vyrez lze zkopirovat do tohoto obrazku
00365                 height <= m_height
00366         )
00367         {
00368                 //zkopirujeme data radek po radku
00369 
00370                 const unsigned char * tmpDataSrc        = (unsigned char*) src->m_data;
00371                 unsigned char * tmpDataDst                      = (unsigned char*) this->m_data;
00372 
00373                 const DWORD pitchSrc = src->GetPitch();
00374                 const DWORD pitchDst = this->GetPitch();                
00375 
00376                 DWORD offsetSrc = ( y * src->m_width + x ) * 3;
00377                 DWORD offsetDst = 0;
00378 
00379                 for ( DWORD dy = 0 ; dy < height ; dy++ )       // pro kazdy radek
00380                 {
00381                         const unsigned char * startSrc  = &tmpDataSrc[ offsetSrc ];
00382                         unsigned char * startDst                = &tmpDataDst[ offsetDst ];
00383 
00384                         offsetSrc += pitchSrc;
00385                         offsetDst += pitchDst;
00386 
00387                         memcpy( startDst, startSrc, sizeof( DWORD ) * width );
00388                 }
00389         }
00390         else
00391         {
00392                 //chybne rozmery vyrezu - nic se nekopiruje
00393         }
00394 }
00395 //OK 2007-09-04 13:35:33 B04-315B\Tom
00396 
00397 // TImageRGB
00398 ////////////////////////////////////////////////////////////////////////////////
00399 ////////////////////////////////////////////////////////////////////////////////
00400 ////////////////////////////////////////////////////////////////////////////////
00401 // TImageGray
00402 
00403 /** Vrati velikost jednoho pixelu v bajtech
00404 */
00405 DWORD TImageGray::GetPixelSize(void) const
00406 {
00407         return 1;
00408 }
00409 //OK 2007-08-25 15:09:23 B04-315B\Tom
00410 
00411 /** Vrati sirku v pixelech.
00412 */
00413 DWORD TImageGray::GetWidth(void) const
00414 {
00415         return m_width;
00416 }
00417 //OK 2007-08-25 15:09:24 B04-315B\Tom
00418 
00419 /** Vrati vysku v pixelech.
00420 */
00421 DWORD TImageGray::GetHeight(void) const
00422 {
00423         return m_height;
00424 }
00425 //OK 2007-08-25 15:09:28 B04-315B\Tom
00426 
00427 /** Vrati pocet bajtu mezi pixely na sousednich radcich.
00428 */
00429 DWORD TImageGray::GetPitch(void) const
00430 {
00431         return m_width * 1;
00432 }
00433 //OK 2007-08-25 15:09:31 B04-315B\Tom
00434 
00435 /** Vrati velikost obrazovych dat v bajtech.
00436 */
00437 DWORD TImageGray::GetDataSize(void) const
00438 {
00439         return m_width * m_height * 1;
00440 }
00441 //OK 2007-08-25 15:09:38 B04-315B\Tom
00442 
00443 /** Vrati obrazova data.
00444 */
00445 const void* TImageGray::GetData(void) const
00446 {
00447         return m_data;
00448 }
00449 //OK 2007-08-25 15:09:47 B04-315B\Tom
00450 
00451 /** Virtualni soukromy destruktor.
00452 */
00453 TImageGray::~TImageGray(void)
00454 {
00455         delete [] m_data;
00456         m_data = NULL;          // can be removed
00457 }
00458 //OK 2007-08-25 15:09:52 B04-315B\Tom
00459 
00460 /** Soukromy konstruktor.
00461 *
00462 *       \param  width   [in] sirka obrazku v pixelech
00463 *       \param  height  [in] vyska obrazku v pixelech
00464 */
00465 TImageGray::TImageGray(DWORD width, DWORD height)
00466 {
00467         m_width         = width;
00468         m_height        = height;
00469 
00470         m_data = new unsigned char[ width * height ];
00471 }
00472 //OK 2007-08-25 15:10:01 B04-315B\Tom
00473 
00474 /** Metoda vytvori obraz z 32-bitoveho formatu ARGB na monochromaticky format.
00475 *
00476 *       \note   Alpha kanal je ignororvan
00477 *
00478 *       \warning        Oba obrazy musi mit stejne rozmery!
00479 *
00480 *       \param  image   [in] obraz ve formatu ARGB
00481 */
00482 void TImageGray::FromARGB( const TImageARGB * image )
00483 {
00484         if (
00485                 this->GetWidth()        != image->GetWidth() ||
00486                 this->GetHeight()       != image->GetHeight()
00487         )
00488         {
00489                 //rozdilna velikost obrazu
00490                 return;
00491         }
00492 
00493         //prekonvertujeme na monochromaticky obraz
00494         //RGB = (0.2989 , 0.5866, 0.1144)
00495 
00496         const DWORD * data = (const DWORD*)image->GetData();
00497         const DWORD pixelCount = this->GetWidth() * this->GetHeight();
00498 
00499         for ( DWORD i = 0 ; i < pixelCount ; i++ ) //pro vsechny pixely
00500         {
00501                 float blue      = (float) ((unsigned char*)&data[i])[0];
00502                 float green     = (float) ((unsigned char*)&data[i])[1];
00503                 float red       = (float) ((unsigned char*)&data[i])[2];
00504 
00505                 float tmp       = 
00506                         red * 0.2989f +
00507                         green * 0.5866f +
00508                         blue * 0.1144f;
00509 
00510                 //TODO OPTIMIZE
00511                 unsigned char res;
00512 #if 1
00513                 //predpoklada se ze vysledek nebude nikdy mensi nez 0
00514                 if ( tmp <= 255.f )
00515                 {
00516                         //vice pravdepodobna varianta
00517                         res = (unsigned char) tmp;
00518                 }
00519                 else
00520                 {
00521                         res = 255;
00522                 }
00523 #else
00524                 //obecne reseni - TMP nikdy 0 byt nemuze - viz vyse - UNSIGNED CHAR rozsh je 0..255
00525                 if ( tmp >= 0.f )
00526                 {
00527                         if ( tmp <= 255.f )
00528                         {
00529                                 res = (unsigned char) tmp;
00530                         }
00531                         else
00532                         {
00533                                 res = 255;
00534                         }
00535                 }
00536                 else
00537                 {
00538                         res = 0;
00539                 }
00540 #endif
00541                 m_data[i] = res;
00542         }
00543 }
00544 //OK 2007-08-25 15:14:49 B04-315B\Tom
00545 
00546 /** Metoda prevede obraz z 24-bitoveho formatu RGB na monochromaticky format.
00547 *
00548 *       \note   Alpha kanal je ignororvan
00549 *
00550 *       \warning        Oba obrazy musi mit stejne rozmery!
00551 *
00552 *       \param  image   [in] obraz ve formatu ARGB
00553 */
00554 void TImageGray::FromRGB( const TImageRGB * image )
00555 {
00556         if (
00557                 this->GetWidth()        != image->GetWidth() ||
00558                 this->GetHeight()       != image->GetHeight()
00559         )
00560         {
00561                 //rozdilna velikost obrazu
00562                 return;
00563         }
00564 
00565         //prekonvertujeme na monochromaticky obraz
00566         //RGB = (0.2989 , 0.5866, 0.1144)
00567 
00568         const unsigned char * src = (unsigned char*)image->GetData();
00569         const DWORD byteCount = image->GetDataSize();
00570 
00571         DWORD offsetSrc = 0;
00572         DWORD offsetDst = 0;
00573 
00574         while ( offsetSrc < byteCount ) 
00575         {
00576                 float blue      = (float) src[ offsetSrc++ ];
00577                 float green     = (float) src[ offsetSrc++ ];
00578                 float red       = (float) src[ offsetSrc++ ];
00579 
00580                 float tmp       = 
00581                         red * 0.2989f +
00582                         green * 0.5866f +
00583                         blue * 0.1144f;
00584 
00585                 //TODO OPTIMIZE
00586                 unsigned char res;
00587 
00588                 //predpoklada se ze vysledek nebude nikdy mensi nez 0
00589                 if ( tmp <= 255.f )
00590                 {
00591                         //vice pravdepodobna varianta
00592                         res = (unsigned char) tmp;
00593                 }
00594                 else
00595                 {
00596                         res = 255;
00597                 }
00598 
00599                 m_data[ offsetDst++ ] = res;
00600         }
00601 }
00602 //OK 2007-09-04 14:04:46 B04-315B\Tom
00603 
00604 /** Metoda zkopiruje zadany vyrez z poskytnuteho obrazku typu GRAY a zkopiruje jej
00605 *       do leveho horniho rohu tohoto obrazu.
00606 *
00607 *       \warning        Velikost vyrezu kopirovaneho obrazu nesmi byt vetsi nez velikost tohoto
00608 *       obrazu. Pokud ano pak metoda neprovede nic. Zaroven musi byt cely vyrez obsazen v poskytnutem
00609 *       obraze.
00610 *
00611 *       \param  src             [in] zdrojovy obraz
00612 *       \param  x               [in] x-souradnice leveho horniho rohu vyrezu
00613 *       \param  y               [in] y-souradnice leveho horniho rohu vyrezu
00614 *       \param  width   [in] sirka vyrezu v pixelech
00615 *       \param  height  [in] vyska vyrezu v pixelech
00616 */
00617 void TImageGray::CopyFrom( const TImageGray * src, DWORD x, DWORD y, DWORD width, DWORD height)
00618 {       
00619         if (
00620                 ( width > 0 ) && ( height > 0 ) &&                      // vyrez musi mit platnou velikost
00621                 src->IsRectInside( x, y, width, height ) &&     //zdrojovy vyrez musi byt uvnitr zdrojoveho obrazku
00622                 width <= m_width &&             // cely vyrez lze zkopirovat do tohoto obrazku
00623                 height <= m_height
00624         )
00625         {
00626                 //zkopirujeme data radek po radku
00627 
00628                 const unsigned char * tmpDataSrc = (unsigned char*) src->m_data;
00629                 unsigned char * tmpDataDst = (unsigned char*) this->m_data;
00630 
00631                 for ( DWORD dy = 0 ; dy < height ; dy++ )
00632                 {
00633                         const unsigned char * startSrc  = &tmpDataSrc[ (y + dy) * src->m_width + x ];
00634                         unsigned char * startDst                = &tmpDataDst[ dy * m_width ];
00635 
00636                         memcpy( startDst, startSrc, sizeof( unsigned char ) * width );
00637                 }
00638         }
00639         else
00640         {
00641                 //chybne rozmery vyrezu - nic se nekopiruje
00642         }
00643 }
00644 //OK 2007-08-26 17:18:44 B04-315B\Tom
00645 
00646 // TImageGray
00647 ////////////////////////////////////////////////////////////////////////////////
00648 ////////////////////////////////////////////////////////////////////////////////
00649 ////////////////////////////////////////////////////////////////////////////////
00650 // TImageSetReal
00651 
00652 /** Vrati obraz typu ARGB.
00653 */
00654 const TImage* TImageSetReal::GetARGB(void) const
00655 {
00656         return m_image_ARGB;
00657 }
00658 //OK 2007-08-25 15:14:55 B04-315B\Tom
00659 
00660 /** Vrati obraz typu GRAY.
00661 */
00662 const TImage* TImageSetReal::GetGray(void) const
00663 {
00664         return m_image_gray;
00665 }
00666 //OK 2007-08-25 15:14:58 B04-315B\Tom
00667 
00668 /** Vrati obraz typu RGB.
00669 */
00670 const TImage* TImageSetReal::GetRGB(void) const
00671 {
00672         return m_image_RGB;
00673 }
00674 //OK 2007-09-04 14:14:34 B04-315B\Tom
00675 
00676 /** Konstruktor.
00677 *
00678 *       \param  manager         [in] manager kde byl tento objekt vytvoren
00679 *       \param  id                      [in] jedinecna identifikace tohoto objektu v manageru
00680 *       \param  width           [in] pozadovana zakladni sirka obrazku
00681 *       \param  height          [in] pozadovana zakladni vyska obrazku
00682 */
00683 TImageSetReal::TImageSetReal(TImageSetManager * manager, DWORD id, DWORD width, DWORD height)
00684 {
00685         m_manager               = manager;
00686         m_managerID             = id;
00687 
00688         m_image_ARGB    = new TImageARGB( width, height ); 
00689         m_image_gray    = new TImageGray( width, height );
00690         m_image_RGB             = new TImageRGB( width, height );
00691 }
00692 //OK 2007-08-25 15:15:47 B04-315B\Tom
00693 //OK 2007-09-04 14:15:30 B04-315B\Tom
00694 
00695 /**     Soukromy virtualni destruktor.
00696 */
00697 TImageSetReal::~TImageSetReal(void)
00698 {
00699         delete m_image_ARGB;
00700         m_image_ARGB = NULL;
00701 
00702         delete m_image_gray;
00703         m_image_gray = NULL;
00704 
00705         delete m_image_RGB;
00706         m_image_RGB = NULL;
00707 }
00708 //OK 2007-08-25 15:15:48 B04-315B\Tom
00709 //OK 2007-09-04 14:15:32 B04-315B\Tom
00710 
00711 // TImageSetReal
00712 ////////////////////////////////////////////////////////////////////////////////
00713 ////////////////////////////////////////////////////////////////////////////////
00714 ////////////////////////////////////////////////////////////////////////////////
00715 // TImageSetManager
00716 
00717 /** Konstruktor.
00718 *
00719 *       Inicializuje manazer.
00720 *
00721 *       \param  width           [in] zakladni sirka obrazku v pixelech - musi byt nenulova
00722 *       \param  height          [in] zakladni vyska obrazku v pixelech - musi byt nenulova
00723 *       \param  initSize        [in] pocatecni mnozstvi predalokovanych obrazku
00724 */
00725 TImageSetManager::TImageSetManager( DWORD width, DWORD height, DWORD initSize )
00726 {
00727         assert(width);
00728         assert(height);
00729 
00730         m_width         = width;
00731         m_height        = height;       
00732 
00733         //naalokujeme obrazky
00734         for( DWORD i = 0 ; i < initSize ; i++ )
00735         {
00736                 //vytvorime obrazek
00737                 TImageSetReal * img = new TImageSetReal( this, i, m_width, m_height );                  
00738                 m_imageSets.push_back(img);
00739                 //oznacime jako volny
00740                 m_imgFlags.push_back(FALSE);    
00741         }
00742 }
00743 //OK 2007-08-25 15:00:34 B04-315B\Tom
00744 
00745 /** Destruktor.
00746 *
00747 *       \warning        Mel by byt volan az v okamziku kdy nejsou zadne zdroje z manageru pouzity v aplikaci.
00748 */
00749 TImageSetManager::~TImageSetManager(void)
00750 {
00751         m_critical.Enter();
00752                 const DWORD size = (DWORD)m_imageSets.size();   
00753                 for( DWORD i = 0 ; i < size ; i++ )
00754                 {               
00755                         delete m_imageSets[i];
00756                         m_imageSets[i] = NULL;
00757                 }
00758         m_critical.Leave();
00759 }
00760 //OK 2007-08-25 15:00:36 B04-315B\Tom
00761 
00762 /** Ziska novy nepouzity obrazek.
00763 *
00764 *       Metoda je synchronizovana s metodou ReleaseImageSet().
00765 *
00766 *       \warning        Muze vratit NULL pokud uz neni zadny obrazek k dispozici.
00767 */ 
00768 TImageSetReal* TImageSetManager::GetImageSet(void)
00769 {
00770         m_critical.Enter();     
00771                 //najdeme prvni nepouzivany obrazek
00772                 DWORD i = 0;
00773                 const DWORD size = (DWORD)m_imageSets.size();
00774                 BOOL found = FALSE;
00775                 while( i < size )
00776                 {
00777                         if ( FALSE == m_imgFlags[i] )
00778                         {
00779                                 //tento obrazek je volny - pouzijeme ho
00780                                 m_imgFlags[i] = TRUE;
00781                                 found = TRUE;
00782                                 break;
00783                         }
00784                         i++;
00785                 }
00786 
00787                 TImageSetReal * ret = NULL;     //ziskany obrazek 
00788                 if(found)
00789                 {
00790                         //nalezli jsme volny obrazek
00791                         ret = m_imageSets[i];
00792                 }
00793                 else
00794                 {
00795 #if 1
00796                         //nemame zadny obrazek - vracime NULL
00797 #else
00798                         //zadny obrazek neni volny - musi alokovat novy a pridat
00799                         //velikost puvodniho pole obrazku je rovna ID noveho obrazku!!!
00800                         ret = new TImageSetReal( this, size, m_width, m_height );
00801                         m_imageSets.push_back(ret);
00802 
00803                         m_imgFlags.push_back(TRUE);     // obrazek uz je pouzit
00804 #endif
00805                 }
00806         m_critical.Leave();
00807 
00808         return ret;
00809 }
00810 //OK 2007-08-25 15:00:50 B04-315B\Tom
00811 
00812 /** Vraceni obrazku zpet do manageru. Timto se tento obrazek stane nepouzivanym
00813 *       a muze byt znovu vracen metodou GetImageSet().
00814 *
00815 *       Metoda je synchronizovana s metodou GetImageSet().
00816 *       
00817 *       \param  img             [in]    objekt s obrazky jednoho snimku
00818 */
00819 void TImageSetManager::ReleaseImageSet(const TImageSetReal * img)
00820 {
00821         m_critical.Enter();
00822 
00823                 const DWORD size        = (DWORD)m_imageSets.size();
00824                 const DWORD id          = img->GetID();
00825                 if(id < size)
00826                 {
00827                         // ID je validni - nastavime prislusny flag
00828                         m_imgFlags[id] = FALSE; // obrazek muze byt znovu pouzit
00829                 }
00830                 else
00831                 {
00832                         // ID nepatri do seznamu obrazku
00833                         assert(false);
00834                 }
00835 
00836         m_critical.Leave();
00837 }
00838 //OK 2007-08-25 15:02:30 B04-315B\Tom
00839 
00840 // TImageSetManager
00841 ////////////////////////////////////////////////////////////////////////////////
00842 ////////////////////////////////////////////////////////////////////////////////
00843 ////////////////////////////////////////////////////////////////////////////////
00844 // TFrameReal
00845 
00846 /** Vrati skupinu obrazu ulozenych v tomto snimku.
00847 */
00848 const TImageSet* TFrameReal::GetImageSet(void) const
00849 {
00850         return m_image;
00851 }
00852 //OK 2007-08-25 15:04:02 B04-315B\Tom
00853 
00854 /** Vrati casovou znacku tohoto objektu.
00855 */
00856 const TTimeStamp & TFrameReal::GetTimestamp(void) const
00857 {
00858         return m_time;
00859 }
00860 //OK 2007-08-25 15:04:05 B04-315B\Tom
00861 
00862 /** Zvyseni poctu referenci na snimek.
00863 */
00864 void TFrameReal::AddRefs(void)
00865 {
00866         m_critSection.Enter();
00867                 m_refs++;               
00868         m_critSection.Leave();
00869 }
00870 //OK 2007-08-25 15:04:16 B04-315B\Tom
00871 
00872 /** Snizeni poctu referenci nad danym snimkem.
00873 *       Po dosazeni poctu referenci na 0 je snimek odstranen.
00874 */
00875 void TFrameReal::Release(void)
00876 {
00877         bool remove = false;
00878 
00879         m_critSection.Enter();
00880                 if( m_refs > 0 )
00881                 {
00882                         m_refs--;
00883                         if( m_refs == 0 )
00884                         {
00885                                 //zrusime objekt - posledni reference byla odstranena
00886                                 remove = true;
00887                         }
00888                         else
00889                         {
00890                                 // objekt ma reference - nic dalsiho se proto nedeje
00891                         }
00892                 }
00893                 else
00894                 {
00895                         //objekt uz nema reference - k tomu by nemelo dojit
00896                         remove = true;
00897                 }
00898         m_critSection.Leave();
00899 
00900         if( remove )
00901         {
00902                 //pokud toto nastane pak uz v aplikaci neni zadna reference a je tedy mozne
00903                 //vynechat synchronizaci
00904                 delete this;
00905         }
00906 }
00907 //OK 2007-08-25 15:04:34 B04-315B\Tom
00908 
00909 /** Vrati pocet referenci na snimek.
00910 */
00911 DWORD TFrameReal::GetRefs(void) const
00912 {
00913         return m_refs;
00914 }
00915 //OK 2007-08-25 15:04:44 B04-315B\Tom
00916 
00917 /** Pridani zamku na tento snimek.
00918 *
00919 *       Zamek muze pridat napriklad vypocetni jednotka pokud je pozadovano, aby
00920 *       dochazelo k synchronizaci zobrazovani s timto snimkem.
00921 *
00922 *       Metoda vraci pocet zamku na snimek po zvyseni poctu zamku.
00923 */
00924 DWORD TFrameReal::AddLock(void)
00925 {
00926         m_critSection2.Enter();
00927                 m_locks++;
00928                 DWORD ret = m_locks;
00929         m_critSection2.Leave();
00930 
00931         return ret;
00932 }
00933 //OK 2007-08-25 15:04:59 B04-315B\Tom
00934 
00935 /** Uvolneni zamku ze snimku.
00936 *
00937 *       Pokud je pocet zamku 0 pak muze snimek opustit frontu snimku a byt zobrazen.
00938 *
00939 *       Metoda vraci pocet zamku na snimek po snizeni poctu zamku.
00940 */
00941 DWORD TFrameReal::ReleaseLock(void)
00942 {
00943         m_critSection2.Enter();
00944                 if( m_locks > 0 )
00945                 {
00946                         m_locks--;
00947                 }
00948                 else
00949                 {
00950                         //CHYBA
00951                 }
00952                 DWORD ret = m_locks;
00953         m_critSection2.Leave();
00954 
00955         return ret;
00956 }
00957 //OK 2007-08-25 15:05:27 B04-315B\Tom
00958 
00959 /** Vrati pocet zamku tohoto snimku.
00960 */
00961 DWORD TFrameReal::GetLockCount(void) const
00962 {
00963         return m_locks;
00964 }
00965 //OK 2007-08-25 15:05:32 B04-315B\Tom
00966 
00967 /** Soukromy virtualni destruktor.
00968 *
00969 *       Je volany z metody TFrameReal::Release() v okamziku kdy
00970 *       je pocet referenci roven 0. Nehrozi tedy kolize s ostatnimi vlakny.
00971 *
00972 *       Automaticky vraci alokovany snimek zpatky do manazeru snimku.
00973 */
00974 TFrameReal::~TFrameReal(void)
00975 {
00976         //musime vratit pouzity snimek
00977         m_image->GetManager()->ReleaseImageSet( m_image );
00978 }
00979 //OK 2007-08-25 15:05:59 B04-315B\Tom
00980 
00981 /** Konstruktor.
00982 *
00983 *       Vytvori objekt s poctem referenci 1, zadnym zamkem a casem vytvoreni rovnym casu volani metody.
00984 *
00985 *       \param  images  [in] snimek ziskany z manazeru - je ulozen v tomto objektu a vracen
00986 *                                       destruktorem
00987 */
00988 TFrameReal::TFrameReal( TImageSetReal * images ):
00989         m_time()
00990 {
00991         m_image = images;
00992 
00993         m_refs = 1;
00994         m_locks = 0;
00995 }
00996 //OK 2007-08-25 15:06:37 B04-315B\Tom
00997 
00998 // TFrameReal
00999 ////////////////////////////////////////////////////////////////////////////////
01000 ////////////////////////////////////////////////////////////////////////////////
01001 ////////////////////////////////////////////////////////////////////////////////

Generated on Sat Nov 17 16:23:26 2007 for Image Processing Pipeline by  doxygen 1.4.6-NO