00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef KINO_PLUGIN_TYPES_H
00021 #define KINO_PLUGIN_TYPES_H
00022
00023 #include "kino_plugin_utility.h"
00024
00025 #include <algorithm>
00026 #include <cmath>
00027 #include <functional>
00028 #include <iostream>
00029 #include <string>
00030 #include <stdint.h>
00031
00032 namespace kino
00033 {
00034
00035
00036 template<typename, typename>
00037 class basic_luma;
00038
00039 template<typename, typename>
00040 class basic_rgb;
00041
00042 template<typename, typename>
00043 class basic_rgba;
00044
00045 class basic_hsv;
00046
00048 typedef unsigned long pixel_size_type;
00049
00051 typedef enum
00052 {
00053 INTERLACE_ALLOWED,
00054 INTERLACE_NOT_ALLOWED,
00055 } interlace_requirement_type;
00056
00058 typedef enum
00059 {
00060 NOT_INTERLACED,
00061 EVEN_FIELD_DOMINANT,
00062 ODD_FIELD_DOMINANT
00063 } interlace_type;
00064
00066 typedef uint8_t uuid_type[16];
00067
00069
00070
00072 template<typename SampleType>
00073 class color_traits
00074 {
00075 public:
00076 typedef SampleType sample_type;
00077
00079 static sample_type minimum();
00081 static sample_type maximum();
00083 static sample_type transparent() { return minimum(); }
00085 static sample_type opaque() { return maximum(); }
00087 static sample_type invert(const sample_type& Sample);
00088 };
00089
00091
00092
00094 template<>
00095 class color_traits<uint8_t>
00096 {
00097 public:
00099 typedef uint8_t sample_type;
00100
00102 static sample_type minimum() { return 0; }
00104 static sample_type maximum() { return 255; }
00106 static sample_type transparent() { return minimum(); }
00108 static sample_type opaque() { return maximum(); }
00110 static sample_type invert(const sample_type& Sample) { return maximum() - Sample; }
00111
00113 static sample_type convert(const sample_type Sample) { return Sample; }
00115 static sample_type convert(const double Sample) { return static_cast<uint8_t>(clamp(Sample, 0.0, 1.0) * maximum()); }
00116 };
00117
00119
00120
00122 template<>
00123 class color_traits<double>
00124 {
00125 public:
00127 typedef double sample_type;
00128
00130 static sample_type minimum() { return 0; }
00132 static sample_type maximum() { return 1; }
00134 static sample_type transparent() { return minimum(); }
00136 static sample_type opaque() { return maximum(); }
00138 static sample_type invert(const sample_type& Sample) { return maximum() - Sample; }
00139
00141 static sample_type convert(const uint8_t Sample) { return static_cast<sample_type>(Sample) / 255.0; }
00143 static sample_type convert(const sample_type Sample) { return Sample; }
00144 };
00145
00147
00148
00150 class basic_hsv
00151 {
00152 public:
00153 typedef double sample_type;
00154 typedef color_traits<sample_type> sample_traits;
00155 typedef basic_hsv this_type;
00156
00158 basic_hsv() :
00159 hue(sample_traits::minimum()),
00160 saturation(sample_traits::minimum()),
00161 value(sample_traits::minimum())
00162 {
00163 }
00164
00166 basic_hsv(const sample_type Hue, const sample_type Saturation, const sample_type Value) :
00167 hue(Hue),
00168 saturation(Saturation),
00169 value(Value)
00170 {
00171 }
00172
00173 template<typename ForeignType, typename ForeignTraits>
00174 basic_hsv(const basic_luma<ForeignType, ForeignTraits>& RHS) :
00175 hue(sample_traits::minimum()),
00176 saturation(sample_traits::minimum()),
00177 value(sample_traits::convert(RHS.luma))
00178 {
00179 }
00180
00181 template<typename ForeignType>
00182 basic_hsv(const ForeignType& RHS)
00183 {
00184 const sample_type red = sample_traits::convert(RHS.red);
00185 const sample_type green = sample_traits::convert(RHS.green);
00186 const sample_type blue = sample_traits::convert(RHS.blue);
00187
00188 const sample_type maxcomponent = std::max(std::max(red, green), blue);
00189 const sample_type mincomponent = std::min(std::min(red, green), blue);
00190 const sample_type difference = maxcomponent - mincomponent;
00191
00192 value = maxcomponent;
00193
00194 saturation = maxcomponent ? difference / maxcomponent : sample_traits::minimum();
00195
00196 if(saturation != sample_traits::minimum())
00197 {
00198 const sample_type reddistance = (maxcomponent - red) / difference;
00199 const sample_type greendistance = (maxcomponent - green) / difference;
00200 const sample_type bluedistance = (maxcomponent - blue) / difference;
00201
00202 if (RHS.red == std::max(std::max(RHS.red, RHS.green), RHS.blue))
00203 {
00204 hue = bluedistance - greendistance;
00205 }
00206 else if (RHS.green == std::max(std::max(RHS.red, RHS.green), RHS.blue))
00207 {
00208 hue = 2 + reddistance - bluedistance;
00209 }
00210 else
00211 {
00212 hue = 4 + greendistance - reddistance;
00213 }
00214
00215 hue *= 60;
00216 while(hue < 0)
00217 hue += 360;
00218 while(hue >= 360)
00219 hue -= 360;
00220 }
00221 else
00222 {
00223 hue = sample_traits::minimum();
00224 }
00225 }
00226
00228 friend std::ostream& operator<<(std::ostream& Stream, const basic_hsv& RHS)
00229 {
00230 Stream << RHS.hue << " " << RHS.saturation << " " << RHS.value;
00231 return Stream;
00232 }
00233
00235 friend std::istream& operator>>(std::istream& Stream, basic_hsv& RHS)
00236 {
00237 Stream >> RHS.hue >> RHS.saturation >> RHS.value;
00238 return Stream;
00239 }
00240
00241 sample_type hue;
00242 sample_type saturation;
00243 sample_type value;
00244 };
00245
00247
00248
00250 template<typename SampleType, typename SampleTraits = color_traits<SampleType> >
00251 class basic_luma
00252 {
00253 public:
00254 typedef SampleType sample_type;
00255 typedef SampleTraits sample_traits;
00256 typedef basic_luma<sample_type, sample_traits> this_type;
00257
00259 basic_luma() :
00260 luma(sample_traits::minimum()),
00261 alpha(sample_traits::opaque())
00262 {
00263 }
00264
00266 basic_luma(const sample_type Luma) :
00267 luma(Luma)
00268 {
00269 }
00270
00271 template<typename ForeignType, typename ForeignTraits>
00272 basic_luma(const basic_luma<ForeignType, ForeignTraits>& RHS) :
00273 luma(sample_traits::convert(RHS.luma))
00274 {
00275 }
00276
00277 template<typename ForeignType, typename ForeignTraits>
00278 basic_luma(const basic_rgb<ForeignType, ForeignTraits>& RHS) :
00279 luma(sample_traits::convert(std::max(RHS.red, std::max(RHS.green, RHS.blue))))
00280 {
00281 }
00282
00283 template<typename ForeignType, typename ForeignTraits>
00284 basic_luma(const basic_rgba<ForeignType, ForeignTraits>& RHS) :
00285 luma(sample_traits::convert(std::max(RHS.red, std::max(RHS.green, RHS.blue))))
00286 {
00287 }
00288
00289 basic_luma(const basic_hsv& RHS) :
00290 luma(sample_traits::convert(RHS.value))
00291 {
00292 }
00293
00295 friend std::ostream& operator<<(std::ostream& Stream, const basic_luma<sample_type, sample_traits>& RHS)
00296 {
00297 Stream << RHS.luma;
00298 return Stream;
00299 }
00300
00302 friend std::istream& operator>>(std::istream& Stream, basic_luma<sample_type, sample_traits>& RHS)
00303 {
00304 Stream >> RHS.luma;
00305 return Stream;
00306 }
00307
00308 sample_type luma;
00309 sample_type alpha;
00310 };
00311
00313
00314
00316 template<typename SampleType, typename SampleTraits = color_traits<SampleType> >
00317 class basic_rgb
00318 {
00319 public:
00320 typedef SampleType sample_type;
00321 typedef SampleTraits sample_traits;
00322 typedef basic_rgb<sample_type, sample_traits> this_type;
00323
00325 basic_rgb() :
00326 red(sample_traits::minimum()),
00327 green(sample_traits::minimum()),
00328 blue(sample_traits::minimum())
00329 {
00330 }
00331
00333 basic_rgb(const sample_type Red, const sample_type Green, const sample_type Blue) :
00334 red(Red),
00335 green(Green),
00336 blue(Blue)
00337 {
00338 }
00339
00340 template<typename ForeignType, typename ForeignTraits>
00341 basic_rgb(const basic_luma<ForeignType, ForeignTraits>& RHS) :
00342 red(sample_traits::convert(RHS.luma)),
00343 green(sample_traits::convert(RHS.luma)),
00344 blue(sample_traits::convert(RHS.luma))
00345 {
00346 }
00347
00348 template<typename ForeignType, typename ForeignTraits>
00349 basic_rgb(const basic_rgb<ForeignType, ForeignTraits>& RHS) :
00350 red(sample_traits::convert(RHS.red)),
00351 green(sample_traits::convert(RHS.green)),
00352 blue(sample_traits::convert(RHS.blue))
00353 {
00354 }
00355
00356 template<typename ForeignType, typename ForeignTraits>
00357 basic_rgb(const basic_rgba<ForeignType, ForeignTraits>& RHS) :
00358 red(sample_traits::convert(RHS.red)),
00359 green(sample_traits::convert(RHS.green)),
00360 blue(sample_traits::convert(RHS.blue))
00361 {
00362 }
00363
00364 basic_rgb(const basic_hsv& RHS)
00365 {
00366
00367 if(0 == RHS.saturation)
00368 {
00369 red = green = blue = sample_traits::convert(RHS.value);
00370 return;
00371 }
00372
00373 const double h = RHS.hue / 60;
00374 const double i = floor(h);
00375 const double f = h - i;
00376 const double p = RHS.value * (1 - RHS.saturation);
00377 const double q = RHS.value * (1 - (RHS.saturation * f));
00378 const double t = RHS.value * (1 - (RHS.saturation * (1 - f)));
00379
00380 if(0.0 == i)
00381 {
00382 red = sample_traits::convert(RHS.value);
00383 green = sample_traits::convert(t);
00384 blue = sample_traits::convert(p);
00385 }
00386 else if(1.0 == i)
00387 {
00388 red = sample_traits::convert(q);
00389 green = sample_traits::convert(RHS.value);
00390 blue = sample_traits::convert(p);
00391 }
00392 else if(2.0 == i)
00393 {
00394 red = sample_traits::convert(p);
00395 green = sample_traits::convert(RHS.value);
00396 blue = sample_traits::convert(t);
00397 }
00398 else if(3.0 == i)
00399 {
00400 red = sample_traits::convert(p);
00401 green = sample_traits::convert(q);
00402 blue = sample_traits::convert(RHS.value);
00403 }
00404 else if(4.0 == i)
00405 {
00406 red = sample_traits::convert(t);
00407 green = sample_traits::convert(p);
00408 blue = sample_traits::convert(RHS.value);
00409 }
00410 else if(5.0 == i)
00411 {
00412 red = sample_traits::convert(RHS.value);
00413 green = sample_traits::convert(p);
00414 blue = sample_traits::convert(q);
00415 }
00416 }
00417
00419 friend std::ostream& operator<<(std::ostream& Stream, const basic_rgb<sample_type, sample_traits>& RHS)
00420 {
00421 Stream << RHS.red << " " << RHS.green << " " << RHS.blue;
00422 return Stream;
00423 }
00424
00426 friend std::istream& operator>>(std::istream& Stream, basic_rgb<sample_type, sample_traits>& RHS)
00427 {
00428 Stream >> RHS.red >> RHS.green >> RHS.blue;
00429 return Stream;
00430 }
00431
00432 sample_type red;
00433 sample_type green;
00434 sample_type blue;
00435 };
00436
00438
00439
00441 template<typename SampleType, typename SampleTraits = color_traits<SampleType> >
00442 class basic_rgba
00443 {
00444 public:
00445 typedef SampleType sample_type;
00446 typedef SampleTraits sample_traits;
00447 typedef basic_rgba<sample_type, sample_traits> this_type;
00448
00450 basic_rgba() :
00451 red(sample_traits::minimum()),
00452 green(sample_traits::minimum()),
00453 blue(sample_traits::minimum()),
00454 alpha(sample_traits::opaque())
00455 {
00456 }
00457
00459 basic_rgba(const sample_type Red, const sample_type Green, const sample_type Blue) :
00460 red(Red),
00461 green(Green),
00462 blue(Blue),
00463 alpha(sample_traits::opaque())
00464 {
00465 }
00466
00468 basic_rgba(const sample_type Red, const sample_type Green, const sample_type Blue, const sample_type Alpha) :
00469 red(Red),
00470 green(Green),
00471 blue(Blue),
00472 alpha(Alpha)
00473 {
00474 }
00475
00476 template<typename ForeignType, typename ForeignTraits>
00477 basic_rgba(const basic_luma<ForeignType, ForeignTraits>& RHS) :
00478 red(sample_traits::convert(RHS.luma)),
00479 green(sample_traits::convert(RHS.luma)),
00480 blue(sample_traits::convert(RHS.luma)),
00481 alpha(sample_traits::opaque())
00482 {
00483 }
00484
00485 template<typename ForeignType, typename ForeignTraits>
00486 basic_rgba(const basic_rgb<ForeignType, ForeignTraits>& RHS) :
00487 red(sample_traits::convert(RHS.red)),
00488 green(sample_traits::convert(RHS.green)),
00489 blue(sample_traits::convert(RHS.blue)),
00490 alpha(sample_traits::opaque())
00491 {
00492 }
00493
00494 template<typename ForeignType, typename ForeignTraits>
00495 basic_rgba(const basic_rgba<ForeignType, ForeignTraits>& RHS) :
00496 red(sample_traits::convert(RHS.red)),
00497 green(sample_traits::convert(RHS.green)),
00498 blue(sample_traits::convert(RHS.blue)),
00499 alpha(sample_traits::convert(RHS.alpha))
00500 {
00501 }
00502
00504 friend std::ostream& operator<<(std::ostream& Stream, const basic_rgba<sample_type, sample_traits>& RHS)
00505 {
00506 Stream << RHS.red << " " << RHS.green << " " << RHS.blue << " " << RHS.alpha;
00507 return Stream;
00508 }
00509
00511 friend std::istream& operator>>(std::istream& Stream, basic_rgba<sample_type, sample_traits>& RHS)
00512 {
00513 Stream >> RHS.red >> RHS.green >> RHS.blue >> RHS.alpha;
00514 return Stream;
00515 }
00516
00517 sample_type red;
00518 sample_type green;
00519 sample_type blue;
00520 sample_type alpha;
00521 };
00522
00524
00525
00527 template<typename PixelType>
00528 class basic_bitmap
00529 {
00530 public:
00531 typedef PixelType pixel_type;
00532 typedef PixelType* iterator;
00533 typedef const PixelType* const_iterator;
00534 typedef basic_bitmap<pixel_type> this_type;
00535
00537 basic_bitmap() :
00538 m_width(0),
00539 m_height(0),
00540 m_data(0)
00541 {
00542 }
00543
00545 basic_bitmap(const pixel_size_type Width, const pixel_size_type Height) :
00546 m_width(Width),
00547 m_height(Height),
00548 m_data(static_cast<pixel_type*>(std::malloc(m_width * m_height * sizeof(pixel_type))))
00549 {
00550
00551 assert(m_width);
00552 assert(m_height);
00553 assert(m_data);
00554 }
00555
00557 basic_bitmap(void* Data, const pixel_size_type Width, const pixel_size_type Height) :
00558 m_width(Width),
00559 m_height(Height),
00560 m_data(static_cast<pixel_type*>(std::malloc(m_width * m_height * sizeof(pixel_type))))
00561 {
00562
00563 assert(m_width);
00564 assert(m_height);
00565 assert(m_data);
00566 assert(Data);
00567
00568 memcpy(m_data, Data, m_width * m_height * sizeof(pixel_type));
00569 }
00570
00572 basic_bitmap(this_type& RHS) :
00573 m_width(RHS.m_width),
00574 m_height(RHS.m_height),
00575 m_data(static_cast<pixel_type*>(std::malloc(m_width * m_height * sizeof(pixel_type))))
00576 {
00577 memcpy(m_data, RHS.m_data, m_width * m_height * sizeof(pixel_type));
00578 }
00580 template<typename ForeignType>
00581 basic_bitmap(basic_bitmap<ForeignType>& RHS) :
00582 m_width(RHS.width()),
00583 m_height(RHS.height()),
00584 m_data(static_cast<pixel_type*>(std::malloc(m_width * m_height * sizeof(pixel_type))))
00585 {
00586 std::copy(RHS.data(), RHS.data() + m_width * m_height, m_data);
00587 }
00588
00590 virtual ~basic_bitmap()
00591 {
00592 clear();
00593 }
00594
00596 pixel_size_type width() const
00597 {
00598 return m_width;
00599 }
00600
00602 pixel_size_type height() const
00603 {
00604 return m_height;
00605 }
00606
00608 const pixel_type* const data() const
00609 {
00610 return m_data;
00611 }
00612
00614 pixel_type* const data()
00615 {
00616 return m_data;
00617 }
00618
00619 void clear()
00620 {
00621 if(m_data)
00622 std::free(m_data);
00623
00624 m_width = 0;
00625 m_height = 0;
00626 m_data = 0;
00627 }
00628
00629 void reset(const pixel_size_type Width, const pixel_size_type Height)
00630 {
00631
00632 assert(Width);
00633 assert(Height);
00634
00635 pixel_type* const data = static_cast<pixel_type*>(std::malloc(Width * Height * sizeof(pixel_type)));
00636 assert(data);
00637
00638 clear();
00639
00640 m_width = Width;
00641 m_height = Height;
00642 m_data = data;
00643 }
00644
00645 iterator begin()
00646 {
00647 return m_data;
00648 }
00649
00650 const_iterator begin() const
00651 {
00652 return m_data;
00653 }
00654
00655 iterator end()
00656 {
00657 return m_data + (m_width * m_height);
00658 }
00659
00660 const_iterator end() const
00661 {
00662 return m_data + (m_width * m_height);
00663 }
00664
00665 private:
00667 pixel_size_type m_width;
00669 pixel_size_type m_height;
00671 PixelType* m_data;
00672 };
00673
00675 typedef basic_rgba<uint8_t> pixel;
00677 typedef basic_bitmap<pixel> video_frame;
00678
00680 class video_sequence
00681 {
00682 public:
00683 typedef video_frame* pointer;
00684 typedef const video_frame* const_pointer;
00685 typedef video_frame& reference;
00686 typedef const video_frame& const_reference;
00687 typedef video_frame value_type;
00688 typedef unsigned long size_type;
00689 typedef long difference_type;
00690
00691 virtual size_type size() const;
00692 virtual bool empty() const;
00693
00694 virtual reference operator[](size_type Offset);
00695 virtual const_reference operator[](size_type Offset) const;
00696
00697 virtual reference front();
00698 virtual const_reference front() const;
00699
00700 virtual reference back();
00701 virtual const_reference back() const;
00702
00703 class iterator :
00704 public std::iterator<std::random_access_iterator_tag, value_type>
00705 {
00706 public:
00707
00708 private:
00709 class implementation;
00710 implementation* const m_implementation;
00711 };
00712
00713 class const_iterator :
00714 public std::iterator<std::random_access_iterator_tag, value_type>
00715 {
00716 public:
00717
00718 private:
00719 class implementation;
00720 implementation* const m_implementation;
00721 };
00722
00723 virtual iterator begin();
00724 virtual const_iterator begin() const;
00725
00726 virtual iterator end();
00727 virtual const_iterator end() const;
00728
00729 protected:
00730 virtual ~video_sequence() {}
00731 };
00732
00734 typedef uint16_t audio_sample;
00735
00737 class audio_sequence
00738 {
00739 public:
00740 typedef audio_sample* pointer;
00741 typedef const audio_sample* const_pointer;
00742 typedef audio_sample& reference;
00743 typedef const audio_sample& const_reference;
00744 typedef audio_sample value_type;
00745 typedef unsigned long size_type;
00746 typedef long difference_type;
00747
00748 ~audio_sequence();
00749
00750 size_type size() const;
00751 bool empty() const;
00752
00753 reference operator[](size_type Offset);
00754 const_reference operator[](size_type Offset) const;
00755
00756 reference front();
00757 const_reference front() const;
00758
00759 reference back();
00760 const_reference back() const;
00761
00762 void push_back(const_reference Value);
00763
00764 class iterator :
00765 public std::iterator<std::random_access_iterator_tag, value_type>
00766 {
00767 public:
00768 iterator(const iterator& RHS);
00769 ~iterator();
00770
00771 iterator& operator=(const iterator& RHS);
00772
00773 iterator& operator++();
00774 iterator operator++(int);
00775
00776 bool operator==(const iterator& RHS) const;
00777
00778 reference operator*() const;
00779
00780 private:
00781 class implementation;
00782 implementation* m_implementation;
00783
00784 public:
00785 iterator(implementation* Implementation);
00786
00787 friend class audio_sequence;
00788 };
00789
00790 class const_iterator :
00791 public std::iterator<std::random_access_iterator_tag, value_type>
00792 {
00793 public:
00794 const_iterator(const const_iterator& RHS);
00795 ~const_iterator();
00796
00797 const_iterator& operator=(const const_iterator& RHS);
00798
00799 const_iterator& operator++();
00800 const_iterator operator++(int);
00801
00802 bool operator==(const const_iterator& RHS) const;
00803
00804 const reference operator*() const;
00805
00806 private:
00807 class implementation;
00808 implementation* const m_implementation;
00809
00810 public:
00811 const_iterator(implementation* Implementation);
00812
00813 friend class audio_sequence;
00814 };
00815
00816 iterator begin();
00817 const_iterator begin() const;
00818
00819 iterator end();
00820 const_iterator end() const;
00821
00822 private:
00823 class implementation;
00824 implementation* const m_implementation;
00825
00826 public:
00827 audio_sequence(implementation* Implementation);
00828 };
00829
00830 }
00831
00832 #endif // !KINO_PLUGIN_TYPES_H