00001 /*!@file Raster/GenericFrame.C Discriminated union of rgb, grayscale, floating-point, and video-yuv images */ 00002 00003 // //////////////////////////////////////////////////////////////////// // 00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2000-2005 // 00005 // by the University of Southern California (USC) and the iLab at USC. // 00006 // See http://iLab.usc.edu for information about this project. // 00007 // //////////////////////////////////////////////////////////////////// // 00008 // Major portions of the iLab Neuromorphic Vision Toolkit are protected // 00009 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency // 00010 // in Visual Environments, and Applications'' by Christof Koch and // 00011 // Laurent Itti, California Institute of Technology, 2001 (patent // 00012 // pending; application number 09/912,225 filed July 23, 2001; see // 00013 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status). // 00014 // //////////////////////////////////////////////////////////////////// // 00015 // This file is part of the iLab Neuromorphic Vision C++ Toolkit. // 00016 // // 00017 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can // 00018 // redistribute it and/or modify it under the terms of the GNU General // 00019 // Public License as published by the Free Software Foundation; either // 00020 // version 2 of the License, or (at your option) any later version. // 00021 // // 00022 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope // 00023 // that it will be useful, but WITHOUT ANY WARRANTY; without even the // 00024 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // 00025 // PURPOSE. See the GNU General Public License for more details. // 00026 // // 00027 // You should have received a copy of the GNU General Public License // 00028 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write // 00029 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, // 00030 // Boston, MA 02111-1307 USA. // 00031 // //////////////////////////////////////////////////////////////////// // 00032 // 00033 // Primary maintainer for this file: Rob Peters <rjpeters at usc dot edu> 00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Raster/GenericFrame.C $ 00035 // $Id: GenericFrame.C 14290 2010-12-01 21:44:03Z itti $ 00036 // 00037 00038 #ifndef RASTER_GENERICFRAME_C_DEFINED 00039 #define RASTER_GENERICFRAME_C_DEFINED 00040 00041 #include "Raster/GenericFrame.H" 00042 00043 #include "Image/ColorOps.H" 00044 #include "Image/Normalize.H" 00045 #include "Util/sformat.H" 00046 #include "Video/VideoFrame.H" 00047 00048 #include <algorithm> // for std::equal() 00049 00050 // ###################################################################### 00051 GenericFrame::MetaData::MetaData() 00052 {} 00053 00054 // ###################################################################### 00055 GenericFrame::MetaData::~MetaData() 00056 {} 00057 00058 // ###################################################################### 00059 GenericFrame::GenericFrame() 00060 : 00061 itsNativeType(GenericFrame::NONE), 00062 itsFloatFlags(0) 00063 {} 00064 00065 // ###################################################################### 00066 GenericFrame::GenericFrame(const Image<PixRGB<byte> >& rgbimg) 00067 : 00068 itsNativeType(rgbimg.initialized() 00069 ? GenericFrame::RGB_U8 00070 : GenericFrame::NONE), 00071 itsRgbU8(rgbimg), 00072 itsFloatFlags(0) 00073 {} 00074 00075 // ###################################################################### 00076 GenericFrame::GenericFrame(const Image<PixRGB<byte> >& rgbimg, const Image<uint16>& dimg) 00077 : 00078 itsNativeType((rgbimg.initialized() && dimg.initialized()) 00079 ? GenericFrame::RGBD 00080 : GenericFrame::NONE), 00081 itsRgbU8(rgbimg), 00082 itsGrayU16(dimg), 00083 itsFloatFlags(0) 00084 { 00085 ASSERT(rgbimg.isSameSize(dimg)); 00086 } 00087 00088 // ###################################################################### 00089 GenericFrame::GenericFrame(const Image<PixRGB<uint16> >& rgbimg) 00090 : 00091 itsNativeType(rgbimg.initialized() 00092 ? GenericFrame::RGB_U16 00093 : GenericFrame::NONE), 00094 itsRgbU8(rgbimg), 00095 itsFloatFlags(0) 00096 {} 00097 00098 // ###################################################################### 00099 GenericFrame::GenericFrame(const Layout<PixRGB<byte> >& rgbimg) 00100 : 00101 itsNativeType(rgbimg.initialized() 00102 ? GenericFrame::RGB_U8 00103 : GenericFrame::NONE), 00104 itsRgbU8(rgbimg), 00105 itsFloatFlags(0) 00106 {} 00107 00108 // ###################################################################### 00109 GenericFrame::GenericFrame(const Image<PixRGB<float> >& rgbimg, 00110 const int flags) 00111 : 00112 itsNativeType(rgbimg.initialized() 00113 ? GenericFrame::RGB_F32 00114 : GenericFrame::NONE), 00115 itsRgbF32(rgbimg), 00116 itsFloatFlags(0) 00117 {} 00118 00119 // ###################################################################### 00120 GenericFrame::GenericFrame(const Image<byte>& grayimg) 00121 : 00122 itsNativeType(grayimg.initialized() 00123 ? GenericFrame::GRAY_U8 00124 : GenericFrame::NONE), 00125 itsGrayU8(grayimg), 00126 itsFloatFlags(0) 00127 {} 00128 00129 // ###################################################################### 00130 GenericFrame::GenericFrame(const Image<uint16>& grayimg) 00131 : 00132 itsNativeType(grayimg.initialized() 00133 ? GenericFrame::GRAY_U16 00134 : GenericFrame::NONE), 00135 itsGrayU16(grayimg), 00136 itsFloatFlags(0) 00137 {} 00138 00139 // ###################################################################### 00140 GenericFrame::GenericFrame(const Layout<byte>& grayimg) 00141 : 00142 itsNativeType(grayimg.initialized() 00143 ? GenericFrame::GRAY_U8 00144 : GenericFrame::NONE), 00145 itsGrayU8(grayimg), 00146 itsFloatFlags(0) 00147 {} 00148 00149 // ###################################################################### 00150 GenericFrame::GenericFrame(const Image<float>& floatimg, 00151 const int flags) 00152 : 00153 itsNativeType(floatimg.initialized() 00154 ? GenericFrame::GRAY_F32 00155 : GenericFrame::NONE), 00156 itsGrayF32(floatimg), 00157 itsFloatFlags(flags) 00158 {} 00159 00160 // ###################################################################### 00161 GenericFrame::GenericFrame(const VideoFrame& vidframe) 00162 : 00163 itsNativeType(vidframe.getDims().isNonEmpty() 00164 ? GenericFrame::VIDEO 00165 : GenericFrame::NONE), 00166 itsVideo(vidframe) 00167 {} 00168 00169 // ###################################################################### 00170 bool GenericFrame::initialized() const 00171 { 00172 if (itsNativeType != NONE) 00173 { 00174 ASSERT(this->getDims().isNonEmpty()); 00175 return true; 00176 } 00177 00178 return false; 00179 } 00180 00181 // ###################################################################### 00182 GenericFrame GenericFrame::deepCopyOf(const GenericFrame& f) 00183 { 00184 GenericFrame result; 00185 result.itsNativeType = f.itsNativeType; 00186 result.itsRgbU8 = f.itsRgbU8; 00187 result.itsRgbU16 = f.itsRgbU16; 00188 result.itsRgbF32 = f.itsRgbF32; 00189 result.itsGrayU8 = f.itsGrayU8; 00190 result.itsGrayU16 = f.itsGrayU16; 00191 result.itsGrayF32 = f.itsGrayF32; 00192 result.itsVideo = VideoFrame::deepCopyOf(f.itsVideo); 00193 result.itsFloatFlags = f.itsFloatFlags; 00194 return result; 00195 } 00196 00197 // ###################################################################### 00198 GenericFrameSpec GenericFrame::frameSpec() const 00199 { 00200 GenericFrameSpec result; 00201 result.nativeType = this->itsNativeType; 00202 result.videoFormat = this->itsVideo.getMode(); 00203 result.videoByteSwap = this->itsVideo.getByteSwap(); 00204 result.dims = this->getDims(); 00205 result.floatFlags = this->itsFloatFlags; 00206 return result; 00207 } 00208 00209 // ###################################################################### 00210 std::string GenericFrame::nativeTypeName() const 00211 { 00212 return this->frameSpec().nativeTypeName(); 00213 } 00214 00215 // ###################################################################### 00216 Dims GenericFrame::getDims() const 00217 { 00218 switch (itsNativeType) 00219 { 00220 case NONE: return Dims(); 00221 case RGB_U8: return itsRgbU8.getDims(); 00222 case RGB_U16: return itsRgbU16.getDims(); 00223 case RGB_F32: return itsRgbF32.getDims(); 00224 case GRAY_U8: return itsGrayU8.getDims(); 00225 case GRAY_U16: return itsGrayU16.getDims(); 00226 case GRAY_F32: return itsGrayF32.getDims(); 00227 case VIDEO: return itsVideo.getDims(); 00228 case RGBD: return itsRgbU8.getDims(); 00229 } 00230 00231 ASSERT(0); /* can't happen */ return Dims(); 00232 } 00233 00234 // ###################################################################### 00235 void GenericFrame::setFloatFlags(int v) 00236 { 00237 if (itsFloatFlags != v) 00238 { 00239 itsFloatFlags = v; 00240 00241 // now, if our native type is floating-point, then we need to 00242 // kill any cached byte versions since they will need to be 00243 // recomputed now that our float-conversion flags have changed 00244 if (itsNativeType == RGB_F32 || itsNativeType == GRAY_F32) 00245 { 00246 itsRgbU8 = Layout<PixRGB<byte> >(); 00247 itsGrayU8 = Layout<byte>(); 00248 itsVideo = VideoFrame(); 00249 } 00250 } 00251 } 00252 00253 // ###################################################################### 00254 const Layout<PixRGB<byte> >& GenericFrame::asRgbU8Layout() const 00255 { 00256 if (!itsRgbU8.initialized()) 00257 { 00258 switch (itsNativeType) 00259 { 00260 case NONE: 00261 // leave itsRgbU8 uninitialized 00262 break; 00263 00264 case RGB_U8: 00265 case RGBD: 00266 break; 00267 00268 case RGB_U16: 00269 break; 00270 00271 case RGB_F32: 00272 // this will possibly do 0..255 normalization (if 00273 // flags&FLOAT_NORM_0_255), possibly add a text indication 00274 // of the original scale (if flags&FLOAT_NORM_WITH_SCALE), 00275 // depending on the user's request: 00276 itsRgbU8 = Layout<PixRGB<byte> >(Image<PixRGB<byte> >(normalizeFloatRgb(itsRgbF32, itsFloatFlags))); 00277 break; 00278 00279 case GRAY_U8: 00280 itsRgbU8 = Layout<PixRGB<byte> >(Image<PixRGB<byte> >(itsGrayU8.render())); 00281 break; 00282 00283 case GRAY_U16: 00284 break; 00285 00286 case GRAY_F32: 00287 // this will possibly do 0..255 normalization (if 00288 // flags&FLOAT_NORM_0_255), possibly add a text indication 00289 // of the original scale (if flags&FLOAT_NORM_WITH_SCALE), 00290 // depending on the user's request: 00291 itsRgbU8 = Layout<PixRGB<byte> >(Image<PixRGB<byte> >(normalizeFloat(itsGrayF32, itsFloatFlags))); 00292 break; 00293 00294 case VIDEO: 00295 itsRgbU8 = Layout<PixRGB<byte> >(itsVideo.toRgb()); 00296 break; 00297 } 00298 } 00299 00300 return itsRgbU8; 00301 } 00302 00303 // ###################################################################### 00304 Image<PixRGB<uint16> > GenericFrame::asRgbU16() const 00305 { 00306 if (!itsRgbU16.initialized()) 00307 { 00308 switch (itsNativeType) 00309 { 00310 case NONE: 00311 break; 00312 case RGB_U8: 00313 case RGBD: 00314 break; 00315 case RGB_U16: 00316 break; 00317 case RGB_F32: 00318 break; 00319 case GRAY_U8: 00320 break; 00321 case GRAY_F32: 00322 break; 00323 case GRAY_U16: 00324 break; 00325 case VIDEO: 00326 itsRgbU16 = itsVideo.toRgbU16(); 00327 } 00328 } 00329 return itsRgbU16; 00330 } 00331 00332 // ###################################################################### 00333 Image<PixRGB<float> > GenericFrame::asRgbF32() const 00334 { 00335 if (!itsRgbF32.initialized()) 00336 { 00337 switch (itsNativeType) 00338 { 00339 case NONE: 00340 // leave itsRgbF32 uninitialized 00341 break; 00342 00343 case RGB_U8: 00344 case RGBD: 00345 itsRgbF32 = itsRgbU8.render(); 00346 break; 00347 00348 case RGB_U16: 00349 break; 00350 00351 case RGB_F32: 00352 break; 00353 00354 case GRAY_U8: 00355 itsRgbF32 = luminance(this->asGrayF32()); 00356 break; 00357 00358 case GRAY_U16: 00359 break; 00360 00361 case GRAY_F32: 00362 itsRgbF32 = itsGrayF32; 00363 break; 00364 00365 case VIDEO: 00366 itsRgbF32 = this->asRgbU8(); 00367 break; 00368 } 00369 } 00370 00371 return itsRgbF32; 00372 } 00373 00374 // ###################################################################### 00375 const Layout<byte>& GenericFrame::asGrayU8Layout() const 00376 { 00377 if (!itsGrayU8.initialized()) 00378 { 00379 switch (itsNativeType) 00380 { 00381 case NONE: 00382 // leave itsGrayU8 uninitialized 00383 break; 00384 00385 case RGB_U8: 00386 itsGrayU8 = Layout<byte>(luminance(itsRgbU8.render())); 00387 break; 00388 00389 case RGB_U16: 00390 case RGBD: 00391 break; 00392 00393 case RGB_F32: 00394 itsGrayU8 = Layout<byte>(luminance(this->asRgbU8())); 00395 break; 00396 00397 case GRAY_U8: 00398 break; 00399 00400 case GRAY_U16: 00401 break; 00402 00403 case GRAY_F32: 00404 // this will possibly do 0..255 normalization (if 00405 // flags&FLOAT_NORM_0_255), possibly add a text indication 00406 // of the original scale (if flags&FLOAT_NORM_WITH_SCALE), 00407 // depending on the user's request: 00408 itsGrayU8 = Layout<byte>(Image<byte>(normalizeFloat(itsGrayF32, itsFloatFlags))); 00409 break; 00410 00411 case VIDEO: 00412 if(itsVideo.getMode() == VIDFMT_BAYER_GB || 00413 itsVideo.getMode() == VIDFMT_BAYER_BG || 00414 itsVideo.getMode() == VIDFMT_BAYER_GR || 00415 itsVideo.getMode() == VIDFMT_BAYER_RG) 00416 { 00417 itsGrayU8 = Image<byte>(itsVideo.getBuffer(),itsVideo.getDims()); 00418 } 00419 else 00420 { 00421 // FIXME: make a VideoFrame::asGray() function to return 00422 // just the Y component from a YUV image 00423 itsGrayU8 = Layout<byte>(luminance(this->asRgbU8())); 00424 } 00425 break; 00426 } 00427 } 00428 00429 return itsGrayU8; 00430 } 00431 00432 00433 // ###################################################################### 00434 const Layout<byte>& GenericFrame::asGrayU8NTSCLayout() const 00435 { 00436 if (!itsGrayU8.initialized()) 00437 { 00438 switch (itsNativeType) 00439 { 00440 case NONE: 00441 // leave itsGrayU8 uninitialized 00442 break; 00443 00444 case RGB_U8: 00445 itsGrayU8 = Layout<byte>(luminanceNTSC(itsRgbU8.render())); 00446 break; 00447 00448 case RGB_U16: 00449 case RGBD: 00450 break; 00451 00452 case RGB_F32: 00453 itsGrayU8 = Layout<byte>(luminanceNTSC(this->asRgbU8())); 00454 break; 00455 00456 case GRAY_U8: 00457 break; 00458 00459 case GRAY_U16: 00460 break; 00461 00462 case GRAY_F32: 00463 // this will possibly do 0..255 normalization (if 00464 // flags&FLOAT_NORM_0_255), possibly add a text indication 00465 // of the original scale (if flags&FLOAT_NORM_WITH_SCALE), 00466 // depending on the user's request: 00467 itsGrayU8 = Layout<byte>(Image<byte>(normalizeFloat(itsGrayF32, itsFloatFlags))); 00468 break; 00469 00470 case VIDEO: 00471 if(itsVideo.getMode() == VIDFMT_BAYER_GB || 00472 itsVideo.getMode() == VIDFMT_BAYER_BG || 00473 itsVideo.getMode() == VIDFMT_BAYER_GR || 00474 itsVideo.getMode() == VIDFMT_BAYER_RG) 00475 { 00476 itsGrayU8 = Image<byte>(itsVideo.getBuffer(),itsVideo.getDims()); 00477 } 00478 else 00479 { 00480 // FIXME: make a VideoFrame::asGray() function to return 00481 // just the Y component from a YUV image 00482 itsGrayU8 = Layout<byte>(luminanceNTSC(this->asRgbU8())); 00483 } 00484 break; 00485 } 00486 } 00487 00488 return itsGrayU8; 00489 } 00490 00491 00492 // ###################################################################### 00493 Image<uint16> GenericFrame::asGrayU16() const 00494 { 00495 if (!itsGrayU16.initialized()) 00496 { 00497 switch(itsNativeType) 00498 { 00499 case NONE: 00500 break; 00501 case RGB_U8: 00502 break; 00503 case RGB_U16: 00504 break; 00505 case RGB_F32: 00506 break; 00507 case GRAY_U8: 00508 break; 00509 case GRAY_U16: 00510 case RGBD: 00511 break; 00512 case GRAY_F32: 00513 break; 00514 case VIDEO: 00515 if(itsVideo.getMode() == VIDFMT_BAYER_GB12 || 00516 itsVideo.getMode() == VIDFMT_BAYER_BG12 || 00517 itsVideo.getMode() == VIDFMT_BAYER_GR12 || 00518 itsVideo.getMode() == VIDFMT_BAYER_RG12) 00519 { 00520 itsGrayU16 = Image<uint16>((uint16*)itsVideo.getBuffer(), 00521 itsVideo.getDims()); 00522 } 00523 break; 00524 } 00525 } 00526 return itsGrayU16; 00527 } 00528 00529 // ###################################################################### 00530 Image<float> GenericFrame::asGrayF32() const 00531 { 00532 if (!itsGrayF32.initialized()) 00533 { 00534 switch (itsNativeType) 00535 { 00536 case NONE: 00537 break; 00538 00539 case RGB_U8: 00540 itsGrayF32 = this->asGray(); 00541 break; 00542 00543 case RGB_U16: 00544 break; 00545 00546 case RGB_F32: 00547 itsGrayF32 = luminance(itsRgbF32); 00548 break; 00549 00550 case GRAY_U8: 00551 itsGrayF32 = itsGrayU8.render(); 00552 break; 00553 00554 case GRAY_U16: 00555 case RGBD: 00556 break; 00557 00558 case GRAY_F32: 00559 break; 00560 00561 case VIDEO: 00562 itsGrayF32 = this->asGray(); 00563 break; 00564 } 00565 } 00566 00567 return itsGrayF32; 00568 } 00569 00570 // ###################################################################### 00571 VideoFrame GenericFrame::asVideo() const 00572 { 00573 if (!itsVideo.initialized()) 00574 { 00575 switch (itsNativeType) 00576 { 00577 case NONE: 00578 break; 00579 00580 case RGB_U8: 00581 case RGBD: 00582 itsVideo = VideoFrame(itsRgbU8.render()); 00583 break; 00584 00585 case RGB_U16: 00586 break; 00587 00588 case RGB_F32: 00589 itsVideo = VideoFrame(this->asRgbU8()); 00590 break; 00591 00592 case GRAY_U8: 00593 itsVideo = VideoFrame(itsGrayU8.render()); 00594 break; 00595 00596 case GRAY_U16: 00597 break; 00598 00599 case GRAY_F32: 00600 // force a conversion from float to gray, then to VideoFrame: 00601 itsVideo = VideoFrame(this->asGray()); 00602 break; 00603 00604 case VIDEO: 00605 break; 00606 } 00607 } 00608 00609 return itsVideo; 00610 } 00611 00612 // ###################################################################### 00613 bool GenericFrame::hasMetaData(const std::string& tag) const 00614 { 00615 if (itsMetaDataMap.get() == 0) 00616 return false; 00617 00618 return itsMetaDataMap->find(tag) != itsMetaDataMap->end(); 00619 } 00620 // ###################################################################### 00621 rutz::shared_ptr<GenericFrame::MetaData> GenericFrame::getMetaData(const std::string& tag) 00622 { 00623 if (itsMetaDataMap.get() != 0) 00624 { 00625 MetaDataMap::iterator itr = itsMetaDataMap->find(tag); 00626 00627 if (itr != itsMetaDataMap->end()) 00628 return (*itr).second; 00629 } 00630 00631 LINFO("Oops: No meta-data with tag '%s'", tag.c_str()); 00632 return rutz::shared_ptr<GenericFrame::MetaData>(); 00633 00634 } 00635 00636 // ###################################################################### 00637 void GenericFrame::addMetaData(const std::string& tag, 00638 rutz::shared_ptr<MetaData> d) 00639 { 00640 if (itsMetaDataMap.get() == 0) 00641 itsMetaDataMap.reset(new MetaDataMap); 00642 00643 itsMetaDataMap->insert(MetaDataMap::value_type(tag, d)); 00644 } 00645 00646 // ###################################################################### 00647 GenericFrameSpec::GenericFrameSpec() 00648 : 00649 nativeType(GenericFrame::NONE), 00650 videoFormat(VIDFMT_AUTO), 00651 videoByteSwap(false), 00652 dims(), 00653 floatFlags(0), 00654 frameRate(0) 00655 {} 00656 00657 // ###################################################################### 00658 bool GenericFrameSpec::operator==(const GenericFrameSpec& that) const 00659 { 00660 return 00661 this->nativeType == that.nativeType 00662 && (this->nativeType != GenericFrame::VIDEO 00663 // consider the video format only if it's actually a 00664 // raw-video frame 00665 || (this->videoFormat == that.videoFormat 00666 && this->videoByteSwap == that.videoByteSwap)) 00667 && this->dims == that.dims 00668 && ((this->nativeType != GenericFrame::RGB_F32 00669 && this->nativeType != GenericFrame::GRAY_F32) 00670 // consider the float flags only if it's actually a 00671 // floating-point format 00672 || this->floatFlags == that.floatFlags); 00673 } 00674 00675 // ###################################################################### 00676 std::string GenericFrameSpec::getDescription() const 00677 { 00678 return sformat("%dx%d %s", 00679 this->dims.w(), this->dims.h(), 00680 this->nativeTypeName().c_str()); 00681 } 00682 00683 // ###################################################################### 00684 std::string GenericFrameSpec::nativeTypeName() const 00685 { 00686 switch (this->nativeType) 00687 { 00688 case GenericFrame::NONE: return "(empty)"; 00689 case GenericFrame::RGB_U8: return "Image<PixRGB<byte>>"; 00690 case GenericFrame::RGB_U16: return "Image<PixRGB<uint16>>"; 00691 case GenericFrame::RGB_F32: return "Image<PixRGB<float>>"; 00692 case GenericFrame::GRAY_U8: return "Image<byte>"; 00693 case GenericFrame::GRAY_U16: return "Image<uint16>"; 00694 case GenericFrame::GRAY_F32: return "Image<float>"; 00695 case GenericFrame::VIDEO: return sformat("VideoFrame (%s%s)", 00696 convertToString(this->videoFormat).c_str(), 00697 this->videoByteSwap 00698 ? "+byteswap" : ""); 00699 case GenericFrame::RGBD: return "Image<PixRGB<byte>>+Image<uint16>"; 00700 } 00701 ASSERT(0); /* can't happen */; return 0; 00702 } 00703 00704 // ###################################################################### 00705 VideoFormat GenericFrameSpec::getActualVideoFormat() const 00706 { 00707 switch (this->nativeType) 00708 { 00709 case GenericFrame::NONE: return VIDFMT_GREY; 00710 case GenericFrame::RGB_U8: return VIDFMT_RGB24; 00711 case GenericFrame::RGBD: return VIDFMT_RGB24; 00712 case GenericFrame::RGB_F32: return VIDFMT_RGB24; 00713 case GenericFrame::GRAY_U8: return VIDFMT_GREY; 00714 case GenericFrame::GRAY_F32: return VIDFMT_GREY; 00715 case GenericFrame::VIDEO: return this->videoFormat; 00716 00717 //undefined byte for the 16 bits RGB or gray scale image 00718 case GenericFrame::RGB_U16: return VIDFMT_AUTO; 00719 case GenericFrame::GRAY_U16: return VIDFMT_AUTO; 00720 } 00721 ASSERT(0); /* can't happen */; return VIDFMT_AUTO; 00722 } 00723 00724 // ###################################################################### 00725 bool operator==(const GenericFrame& f1, const GenericFrame& f2) 00726 { 00727 if (f1.nativeType() == f2.nativeType()) 00728 { 00729 switch (f1.nativeType()) 00730 { 00731 case GenericFrame::NONE: return true; 00732 case GenericFrame::RGB_U8: return f1.asRgbU8() == f2.asRgbU8(); 00733 case GenericFrame::RGBD: return ((f1.asRgbU8() == f2.asRgbU8()) && (f1.asGrayU16() == f2.asGrayU16())); 00734 case GenericFrame::RGB_F32: return f1.asRgbF32() == f2.asRgbF32(); 00735 case GenericFrame::GRAY_U8: return f1.asGrayU8() == f2.asGrayU8(); 00736 case GenericFrame::GRAY_F32: return f1.asGrayF32() == f2.asGrayF32(); 00737 case GenericFrame::VIDEO: 00738 { 00739 const VideoFrame v1 = f1.asVideo(); 00740 const VideoFrame v2 = f2.asVideo(); 00741 00742 if (v1.getMode() == v2.getMode()) 00743 return std::equal(v1.getBuffer(), 00744 v1.getBuffer() + v1.getBufSize(), 00745 v2.getBuffer()); 00746 else 00747 return v1.toRgb() == v2.toRgb(); 00748 } 00749 case GenericFrame::RGB_U16: return f1.asRgbU16() == f2.asRgbU16(); 00750 case GenericFrame::GRAY_U16: return f1.asGrayU16() == f2.asGrayU16(); 00751 } 00752 } 00753 00754 return f1.asRgbF32() == f2.asRgbF32(); 00755 } 00756 00757 // ###################################################################### 00758 /* So things look consistent in everyone's emacs... */ 00759 /* Local Variables: */ 00760 /* mode: c++ */ 00761 /* indent-tabs-mode: nil */ 00762 /* End: */ 00763 00764 #endif // RASTER_GENERICFRAME_C_DEFINED