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
00030
00031
00032
00033
00034
00035
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>
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); return Dims();
00232 }
00233
00234
00235 void GenericFrame::setFloatFlags(int v)
00236 {
00237 if (itsFloatFlags != v)
00238 {
00239 itsFloatFlags = v;
00240
00241
00242
00243
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
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
00273
00274
00275
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
00288
00289
00290
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
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
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
00405
00406
00407
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
00422
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
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
00464
00465
00466
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
00481
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
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
00664
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
00671
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); ; 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
00718 case GenericFrame::RGB_U16: return VIDFMT_AUTO;
00719 case GenericFrame::GRAY_U16: return VIDFMT_AUTO;
00720 }
00721 ASSERT(0); ; 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
00759
00760
00761
00762
00763
00764 #endif // RASTER_GENERICFRAME_C_DEFINED