TLIGHT_PRODUCTS / WS281X
Revision:
27:bc79f444883b
Child:
28:b452e097da53
diff -r 7860372ae448 -r bc79f444883b PixelBuffer.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/PixelBuffer.cpp	Tue Sep 06 22:12:59 2016 +0000
@@ -0,0 +1,323 @@
+/* PixelBuffer.cpp
+ * mbed Microcontroller Library
+ * Copyright (c) 2016 muetch, t.kuroki
+ * Allrights reserved.
+ *
+ * Rev 0.97 2016-09-07
+ */
+#include "PixelBuffer.h"
+
+//----------------------------------------------------------------------------
+// 指定されたバッファの先頭からblock_size分をbuf_sizeが満杯になるまで繰り返しコピーする
+template <class T>
+static void repeat_buffer(T *buffer, int buf_size, int block_size = 1)
+{
+    if (buffer && block_size > 0 && (uint16_t)block_size < buf_size)
+    {
+        T *dest = buffer + block_size;
+        int left = buf_size - block_size;
+        while (left > block_size)
+        {
+            memcpy(dest, buffer, block_size * sizeof(T));
+            dest += block_size;
+            left -= block_size;
+            block_size <<= 1;       // 次回は2倍のサイズの転送
+        }
+        memcpy(dest, buffer, left * sizeof(T));
+    }
+} 
+
+//----------------------------------------------------------------------------
+RGBPixels::RGBPixels(RGBColor *buffer, int maxPixels)
+    : _buf_owner(false)
+{
+    _dummyPixel = 0;
+    setPixelBuffer(buffer, maxPixels);
+}
+
+RGBPixels::RGBPixels(int maxPixels)
+    : _buf_owner(false)
+{
+    _dummyPixel = 0;
+    setPixelBuffer(nullptr, maxPixels);
+}
+
+RGBPixels::~RGBPixels()
+{
+    if (_buf_owner && _pixels)
+        delete[] _pixels;
+}
+
+void RGBPixels::setPixelBuffer(RGBColor *buffer, int maxPixels)
+{
+    if (_buf_owner && _pixels)
+        delete[] _pixels;
+
+    _buf_owner = false;
+    _pixels = buffer;
+
+    _maxPixels = (maxPixels < 0) ? 0 : (maxPixels > MAX_PIXELS) ? MAX_PIXELS : maxPixels;
+    if (!_pixels && _maxPixels > 0)
+    {
+        _pixels = new RGBColor[_maxPixels];
+        _buf_owner = true;   
+    }
+    _numPixels = _maxPixels;
+    clear();
+}
+
+int RGBPixels::numPixels(int value)
+{
+    if (value >= 0)
+        _numPixels = (value > _maxPixels) ? _maxPixels : value;
+    return _numPixels;
+}
+
+// 指定位置のピクセルへ色配列を指定サイズ分をコピーする
+void RGBPixels::setPixels(int index, RGBColor *color, int len)
+{
+    if (_pixels && len > 0 && (uint16_t)index < _numPixels)
+    {
+        if (index + len > _numPixels)
+            len = _numPixels - index;
+        memcpy(&_pixels[index], color, len * sizeof(_pixels[0]));
+    }
+}
+
+void RGBPixels::setPixels(int index, HSVColor *color, int len)
+{
+    if (_pixels && len > 0 && (uint16_t)index < _numPixels)
+    {
+        if (index + len > _numPixels)
+            len = _numPixels - index;
+        RGBColor *dest = &_pixels[index];
+        do
+        {
+            *dest++ = *color++;
+        } while (--len);
+    }
+}
+
+// 指定色を指定位置のピクセルから指定サイズ分書き込む
+void RGBPixels::fillPixels(const RGBColor color, int index, int len)
+{
+    if (_pixels && len > 0 && (uint16_t)index < _numPixels)
+    {
+        if (index + len > _numPixels)
+            len = _numPixels - index;
+        _pixels[index] = color;
+        repeat_buffer<RGBColor>(_pixels + index, len, 1);
+    }
+}
+
+void RGBPixels::fillPixels(const HSVColor color, int index, int len)
+{
+    fillPixels(RGBColor(color), index, len);
+}
+
+// 先頭から指定サイズ分のブロックをバッファの最後までコピーする
+void RGBPixels::repeatPixels(int block_size)
+{
+    if (_pixels && block_size > 0 && block_size < _numPixels)
+    {
+        repeat_buffer<RGBColor>(_pixels, _numPixels, block_size);
+    }
+}
+
+void RGBPixels::repeatPixels(RGBColor *source, int size)
+{
+    if (_pixels && source && size > 0)
+    {
+        if (size > _numPixels)
+            size = _numPixels;
+        memcpy(_pixels, source, size * sizeof(_pixels[0]));
+        repeat_buffer<RGBColor>(_pixels, _numPixels, size);
+    }
+}
+
+void RGBPixels::repeatPixels(HSVColor *source, int size)
+{
+    if (_pixels && source && size > 0)
+    {
+        if (size > _numPixels)
+            size = _numPixels;
+        for (int i = 0; i < size; ++i)
+            _pixels[i] = *source++;
+        repeat_buffer<RGBColor>(_pixels, _numPixels, size);
+    }
+}
+
+RGBPixels& RGBPixels::operator=(const RGBPixels& rhs)
+{
+    if (!rhs._pixels || !rhs._maxPixels)
+    {
+        // 右辺が空の場合何もしない
+        return *this;
+    }
+    if (!_pixels || !_maxPixels)
+    {
+        // 自分のバッファなしの場合、、新規確保
+        setPixelBuffer(nullptr, rhs._maxPixels);
+    }
+
+    if (_pixels && _maxPixels)
+    {
+        _numPixels = rhs._numPixels;
+        if (_numPixels > rhs._maxPixels)
+            _numPixels = rhs._maxPixels;
+        if (_numPixels > _maxPixels)
+            _numPixels = _maxPixels;
+        memcpy(_pixels, rhs._pixels, sizeof(_pixels[0]) * _numPixels);
+    }
+
+    return *this;
+}
+
+//----------------------------------------------------------------------------
+//----------------------------------------------------------------------------
+HSVPixels::HSVPixels(HSVColor *buffer, int maxPixels)
+    : _buf_owner(false)
+{
+    _dummyPixel = 0;
+    setPixelBuffer(buffer, maxPixels);
+}
+
+HSVPixels::HSVPixels(int maxPixels)
+    : _buf_owner(false)
+{
+    _dummyPixel = 0;
+    setPixelBuffer(nullptr, maxPixels);
+}
+
+HSVPixels::~HSVPixels()
+{
+    if (_buf_owner && _pixels)
+        delete[] _pixels;
+}
+
+void HSVPixels::setPixelBuffer(HSVColor *buffer, int maxPixels)
+{
+    if (_buf_owner && _pixels)
+        delete[] _pixels;
+
+    _buf_owner = false;
+    _pixels = buffer;
+
+    _maxPixels = (maxPixels < 0) ? 0 : (maxPixels > MAX_PIXELS) ? MAX_PIXELS : maxPixels;
+    if (!_pixels && _maxPixels > 0)
+    {
+        _pixels = new HSVColor[_maxPixels];
+        _buf_owner = true;   
+    }
+    _numPixels = _maxPixels;
+    clear();
+}
+
+int HSVPixels::numPixels(int value)
+{
+    if (value >= 0)
+        _numPixels = (value > _maxPixels) ? _maxPixels : value;
+    return _numPixels;
+}
+
+// 指定位置のピクセルへ色配列を指定サイズ分をコピーする
+void HSVPixels::setPixels(int index, HSVColor *color, int len)
+{
+    if (_pixels && len > 0 && (uint16_t)index < _numPixels)
+    {
+        if (index + len > _numPixels)
+            len = _numPixels - index;
+        memcpy(&_pixels[index], color, len * sizeof(_pixels[0]));
+    }
+}
+
+void HSVPixels::setPixels(int index, RGBColor *color, int len)
+{
+    if (_pixels && len > 0 && (uint16_t)index < _numPixels)
+    {
+        if (index + len > _numPixels)
+            len = _numPixels - index;
+        HSVColor *dest = &_pixels[index];
+        do
+        {
+            *dest++ = *color++;
+        } while (--len);
+    }
+}
+
+// 指定色を指定位置のピクセルから指定サイズ分書き込む
+void HSVPixels::fillPixels(const HSVColor color, int index, int len)
+{
+    if (_pixels && len > 0 && (uint16_t)index < _numPixels)
+    {
+        if (index + len > _numPixels)
+            len = _numPixels - index;
+        _pixels[index] = color;
+        repeat_buffer<HSVColor>(_pixels + index, len, 1);
+    }
+}
+
+void HSVPixels::fillPixels(const RGBColor color, int index, int len)
+{
+    fillPixels(HSVColor(color), index, len);
+}
+
+// 先頭から指定サイズ分のブロックをバッファの最後までコピーする
+void HSVPixels::repeatPixels(int block_size)
+{
+    if (_pixels && block_size > 0 && block_size < _numPixels)
+    {
+        repeat_buffer<HSVColor>(_pixels, _numPixels, block_size);
+    }
+}
+
+void HSVPixels::repeatPixels(HSVColor *source, int size)
+{
+    if (_pixels && source && size > 0)
+    {
+        if (size > _numPixels)
+            size = _numPixels;
+        memcpy(_pixels, source, size * sizeof(_pixels[0]));
+        repeat_buffer<HSVColor>(_pixels, _numPixels, size);
+    }
+}
+
+void HSVPixels::repeatPixels(RGBColor *source, int size)
+{
+    if (_pixels && source && size > 0)
+    {
+        if (size > _numPixels)
+            size = _numPixels;
+        for (int i = 0; i < size; ++i)
+            _pixels[i] = *source++;
+        repeat_buffer<HSVColor>(_pixels, _numPixels, size);
+    }
+}
+
+HSVPixels& HSVPixels::operator=(const HSVPixels& rhs)
+{
+    if (!rhs._pixels || !rhs._maxPixels)
+    {
+        // 右辺が空の場合何もしない
+        return *this;
+    }
+    if (!_pixels || !_maxPixels)
+    {
+        // 自分のバッファなしの場合、、新規確保
+        setPixelBuffer(nullptr, rhs._maxPixels);
+    }
+
+    if (_pixels && _maxPixels)
+    {
+        _numPixels = rhs._numPixels;
+        if (_numPixels > rhs._maxPixels)
+            _numPixels = rhs._maxPixels;
+        if (_numPixels > _maxPixels)
+            _numPixels = _maxPixels;
+        memcpy(_pixels, rhs._pixels, sizeof(_pixels[0]) * _numPixels);
+    }
+
+    return *this;
+}
+
+//----------------------------------------------------------------------------