diff --git a/format b/format new file mode 100755 index 00000000..c5630b48 --- /dev/null +++ b/format @@ -0,0 +1 @@ +git diff -U0 --no-color HEAD^ | clang-format-diff -i -p1 \ No newline at end of file diff --git a/inc/rlottie_capi.h b/inc/rlottie_capi.h index 72d78be3..afe324da 100644 --- a/inc/rlottie_capi.h +++ b/inc/rlottie_capi.h @@ -46,6 +46,36 @@ typedef enum { typedef struct Lottie_Animation_S Lottie_Animation; +/** + * @brief Runs lottie initialization code when rlottie library is loaded + * dynamically. + * + * + * This api should be called before any other api when rlottie library + * is loaded using dlopen() or equivalent. + * + * @see lottie_shutdown() + * + * @ingroup Lottie_Animation + * @internal + */ +RLOTTIE_API void lottie_init(void); + +/** + * @brief Runs lottie teardown code when rlottie library is loaded + * dynamically. + * + * This api should be called before unloading the rlottie library for + * proper cleanup of the resource without doing so will result in undefined + * behaviour. + * + * @see lottie_init() + * + * @ingroup Lottie_Animation + * @internal + */ +RLOTTIE_API void lottie_shutdown(void); + /** * @brief Constructs an animation object from file path. * diff --git a/src/binding/c/lottieanimation_capi.cpp b/src/binding/c/lottieanimation_capi.cpp index 15486300..4a34fe91 100644 --- a/src/binding/c/lottieanimation_capi.cpp +++ b/src/binding/c/lottieanimation_capi.cpp @@ -26,6 +26,9 @@ using namespace rlottie; +extern void lottie_init_impl(); +extern void lottie_shutdown_impl(); + extern "C" { #include #include @@ -38,6 +41,34 @@ struct Lottie_Animation_S LOTMarkerList *mMarkerList; }; +static uint32_t _lottie_lib_ref_count = 0; + +RLOTTIE_API void lottie_init(void) +{ + if (_lottie_lib_ref_count > 0) { + _lottie_lib_ref_count++; + return; + } + lottie_init_impl(); + + _lottie_lib_ref_count = 1; +} + +RLOTTIE_API void lottie_shutdown(void) +{ + if (_lottie_lib_ref_count <= 0) { + // lottie_init() is not called before lottie_shutdown() + // or multiple shutdown is getting called. + return; + } + + _lottie_lib_ref_count--; + + if (_lottie_lib_ref_count == 0) { + lottie_shutdown_impl(); + } +} + RLOTTIE_API Lottie_Animation_S *lottie_animation_from_file(const char *path) { if (auto animation = Animation::loadFromFile(path) ) { diff --git a/src/lottie/lottieanimation.cpp b/src/lottie/lottieanimation.cpp index 6cc32a60..ea7f873f 100644 --- a/src/lottie/lottieanimation.cpp +++ b/src/lottie/lottieanimation.cpp @@ -213,20 +213,29 @@ class RenderTaskScheduler { for (unsigned n = 0; n != _count; ++n) { _threads.emplace_back([&, n] { run(n); }); } + + IsRunning = true; } public: + static bool IsRunning; + static RenderTaskScheduler &instance() { static RenderTaskScheduler singleton; return singleton; } - ~RenderTaskScheduler() + ~RenderTaskScheduler() { stop(); } + + void stop() { - for (auto &e : _q) e.done(); + if (IsRunning) { + IsRunning = false; - for (auto &e : _threads) e.join(); + for (auto &e : _q) e.done(); + for (auto &e : _threads) e.join(); + } } std::future process(SharedRenderTask task) @@ -249,12 +258,16 @@ class RenderTaskScheduler { #else class RenderTaskScheduler { public: + static bool IsRunning; + static RenderTaskScheduler &instance() { static RenderTaskScheduler singleton; return singleton; } + void stop() {} + std::future process(SharedRenderTask task) { auto result = task->playerImpl->render(task->frameNo, task->surface, @@ -263,8 +276,11 @@ class RenderTaskScheduler { return std::move(task->receiver); } }; + #endif +bool RenderTaskScheduler::IsRunning{false}; + std::future AnimationImpl::renderAsync(size_t frameNo, Surface &&surface, bool keepAspectRatio) @@ -481,6 +497,29 @@ void Surface::setDrawRegion(size_t x, size_t y, size_t width, size_t height) mDrawArea.h = height; } +namespace { +void lottieShutdownRenderTaskScheduler() +{ + if (RenderTaskScheduler::IsRunning) { + RenderTaskScheduler::instance().stop(); + } +} +} // namespace + +// private apis exposed to c interface +void lottie_init_impl() +{ + // do nothing for now. +} + +extern void lottieShutdownRasterTaskScheduler(); + +void lottie_shutdown_impl() +{ + lottieShutdownRenderTaskScheduler(); + lottieShutdownRasterTaskScheduler(); +} + #ifdef LOTTIE_LOGGING_SUPPORT void initLogging() { diff --git a/src/lottie/lottiefiltermodel.h b/src/lottie/lottiefiltermodel.h index b2b98b19..4f78c11a 100644 --- a/src/lottie/lottiefiltermodel.h +++ b/src/lottie/lottiefiltermodel.h @@ -238,7 +238,7 @@ class FilterData { public: void addValue(LOTVariant& value) { - uint index = static_cast(value.property()); + uint32_t index = static_cast(value.property()); if (mBitset.test(index)) { std::replace_if(mFilters.begin(), mFilters.end(), [&value](const LOTVariant& e) { @@ -253,7 +253,7 @@ class FilterData { void removeValue(LOTVariant& value) { - uint index = static_cast(value.property()); + uint32_t index = static_cast(value.property()); if (mBitset.test(index)) { mBitset.reset(index); mFilters.erase(std::remove_if(mFilters.begin(), mFilters.end(), @@ -266,7 +266,7 @@ class FilterData { } bool hasFilter(rlottie::Property prop) const { - return mBitset.test(static_cast(prop)); + return mBitset.test(static_cast(prop)); } model::Color color(rlottie::Property prop, int frame) const { diff --git a/src/lottie/lottieitem.cpp b/src/lottie/lottieitem.cpp index 466d4869..d68ae366 100644 --- a/src/lottie/lottieitem.cpp +++ b/src/lottie/lottieitem.cpp @@ -178,9 +178,9 @@ bool renderer::Composition::updatePartial(int frameNo, const VSize &size, bool renderer::Composition::render(const rlottie::Surface &surface) { - mSurface.reset(reinterpret_cast(surface.buffer()), - uint(surface.width()), uint(surface.height()), - uint(surface.bytesPerLine()), + mSurface.reset(reinterpret_cast(surface.buffer()), + uint32_t(surface.width()), uint32_t(surface.height()), + uint32_t(surface.bytesPerLine()), VBitmap::Format::ARGB32_Premultiplied); /* schedule all preprocess task for this frame at once. @@ -253,7 +253,7 @@ VRle renderer::Mask::rle() { if (!vCompare(mCombinedAlpha, 1.0f)) { VRle obj = mRasterizer.rle(); - obj *= uchar(mCombinedAlpha * 255); + obj *= uint8_t(mCombinedAlpha * 255); return obj; } else { return mRasterizer.rle(); @@ -396,7 +396,7 @@ renderer::Layer::Layer(model::Layer *layerData) : mLayerData(layerData) mLayerMask = std::make_unique(mLayerData); } -bool renderer::Layer::resolveKeyPath(LOTKeyPath &keyPath, uint depth, +bool renderer::Layer::resolveKeyPath(LOTKeyPath &keyPath, uint32_t depth, LOTVariant &value) { if (!keyPath.matches(name(), depth)) { @@ -412,12 +412,12 @@ bool renderer::Layer::resolveKeyPath(LOTKeyPath &keyPath, uint depth, return true; } -bool renderer::ShapeLayer::resolveKeyPath(LOTKeyPath &keyPath, uint depth, +bool renderer::ShapeLayer::resolveKeyPath(LOTKeyPath &keyPath, uint32_t depth, LOTVariant &value) { if (renderer::Layer::resolveKeyPath(keyPath, depth, value)) { if (keyPath.propagate(name(), depth)) { - uint newDepth = keyPath.nextDepth(name(), depth); + uint32_t newDepth = keyPath.nextDepth(name(), depth); mRoot->resolveKeyPath(keyPath, newDepth, value); } return true; @@ -425,12 +425,12 @@ bool renderer::ShapeLayer::resolveKeyPath(LOTKeyPath &keyPath, uint depth, return false; } -bool renderer::CompLayer::resolveKeyPath(LOTKeyPath &keyPath, uint depth, +bool renderer::CompLayer::resolveKeyPath(LOTKeyPath &keyPath, uint32_t depth, LOTVariant &value) { if (renderer::Layer::resolveKeyPath(keyPath, depth, value)) { if (keyPath.propagate(name(), depth)) { - uint newDepth = keyPath.nextDepth(name(), depth); + uint32_t newDepth = keyPath.nextDepth(name(), depth); for (const auto &layer : mLayers) { layer->resolveKeyPath(keyPath, newDepth, value); } @@ -560,7 +560,7 @@ void renderer::CompLayer::render(VPainter *painter, const VRle &inheritMask, renderHelper(&srcPainter, inheritMask, matteRle, cache); srcPainter.end(); painter->drawBitmap(VPoint(), srcBitmap, - uchar(combinedAlpha() * 255.0f)); + uint8_t(combinedAlpha() * 255.0f)); cache.release_surface(srcBitmap); } else { renderHelper(painter, inheritMask, matteRle, cache); @@ -916,7 +916,7 @@ renderer::DrawableList renderer::ShapeLayer::renderList() return {mDrawableList.data(), mDrawableList.size()}; } -bool renderer::Group::resolveKeyPath(LOTKeyPath &keyPath, uint depth, +bool renderer::Group::resolveKeyPath(LOTKeyPath &keyPath, uint32_t depth, LOTVariant &value) { if (!keyPath.skip(name())) { @@ -933,7 +933,7 @@ bool renderer::Group::resolveKeyPath(LOTKeyPath &keyPath, uint depth, } if (keyPath.propagate(name(), depth)) { - uint newDepth = keyPath.nextDepth(name(), depth); + uint32_t newDepth = keyPath.nextDepth(name(), depth); for (auto &child : mContents) { child->resolveKeyPath(keyPath, newDepth, value); } @@ -941,7 +941,7 @@ bool renderer::Group::resolveKeyPath(LOTKeyPath &keyPath, uint depth, return true; } -bool renderer::Fill::resolveKeyPath(LOTKeyPath &keyPath, uint depth, +bool renderer::Fill::resolveKeyPath(LOTKeyPath &keyPath, uint32_t depth, LOTVariant &value) { if (!keyPath.matches(mModel.name(), depth)) { @@ -956,7 +956,7 @@ bool renderer::Fill::resolveKeyPath(LOTKeyPath &keyPath, uint depth, return false; } -bool renderer::Stroke::resolveKeyPath(LOTKeyPath &keyPath, uint depth, +bool renderer::Stroke::resolveKeyPath(LOTKeyPath &keyPath, uint32_t depth, LOTVariant &value) { if (!keyPath.matches(mModel.name(), depth)) { diff --git a/src/lottie/lottieitem.h b/src/lottie/lottieitem.h index bc7f2e83..b9dc2c5b 100644 --- a/src/lottie/lottieitem.h +++ b/src/lottie/lottieitem.h @@ -80,7 +80,7 @@ namespace renderer { using DrawableList = VSpan; -enum class DirtyFlagBit : uchar { +enum class DirtyFlagBit : uint8_t { None = 0x00, Matrix = 0x01, Alpha = 0x02, @@ -242,8 +242,8 @@ class Layer { std::vector & cmasks() { return mCApiData->mMasks; } std::vector & cnodes() { return mCApiData->mCNodeList; } const char * name() const { return mLayerData->name(); } - virtual bool resolveKeyPath(LOTKeyPath &keyPath, uint depth, - LOTVariant &value); + virtual bool resolveKeyPath(LOTKeyPath &keyPath, uint32_t depth, + LOTVariant &value); protected: virtual void preprocessStage(const VRect &clip) = 0; @@ -278,7 +278,7 @@ class CompLayer final : public Layer { void render(VPainter *painter, const VRle &mask, const VRle &matteRle, SurfaceCache &cache) final; void buildLayerNode() final; - bool resolveKeyPath(LOTKeyPath &keyPath, uint depth, + bool resolveKeyPath(LOTKeyPath &keyPath, uint32_t depth, LOTVariant &value) override; protected: @@ -320,7 +320,7 @@ class ShapeLayer final : public Layer { explicit ShapeLayer(model::Layer *layerData, VArenaAlloc *allocator); DrawableList renderList() final; void buildLayerNode() final; - bool resolveKeyPath(LOTKeyPath &keyPath, uint depth, + bool resolveKeyPath(LOTKeyPath &keyPath, uint32_t depth, LOTVariant &value) override; protected: @@ -358,13 +358,13 @@ class ImageLayer final : public Layer { class Object { public: - enum class Type : uchar { Unknown, Group, Shape, Paint, Trim }; + enum class Type : uint8_t { Unknown, Group, Shape, Paint, Trim }; virtual ~Object() = default; Object & operator=(Object &&) noexcept = delete; virtual void update(int frameNo, const VMatrix &parentMatrix, float parentAlpha, const DirtyFlag &flag) = 0; virtual void renderList(std::vector &) {} - virtual bool resolveKeyPath(LOTKeyPath &, uint, LOTVariant &) + virtual bool resolveKeyPath(LOTKeyPath &, uint32_t, LOTVariant &) { return false; } @@ -390,7 +390,7 @@ class Group : public Object { static const char *TAG = "__"; return mModel.hasModel() ? mModel.name() : TAG; } - bool resolveKeyPath(LOTKeyPath &keyPath, uint depth, + bool resolveKeyPath(LOTKeyPath &keyPath, uint32_t depth, LOTVariant &value) override; protected: @@ -535,7 +535,7 @@ class Fill final : public Paint { protected: bool updateContent(int frameNo, const VMatrix &matrix, float alpha) final; - bool resolveKeyPath(LOTKeyPath &keyPath, uint depth, + bool resolveKeyPath(LOTKeyPath &keyPath, uint32_t depth, LOTVariant &value) final; private: @@ -560,7 +560,7 @@ class Stroke : public Paint { protected: bool updateContent(int frameNo, const VMatrix &matrix, float alpha) final; - bool resolveKeyPath(LOTKeyPath &keyPath, uint depth, + bool resolveKeyPath(LOTKeyPath &keyPath, uint32_t depth, LOTVariant &value) final; private: diff --git a/src/lottie/lottieitem_capi.cpp b/src/lottie/lottieitem_capi.cpp index 6f6fb950..31ca54a6 100644 --- a/src/lottie/lottieitem_capi.cpp +++ b/src/lottie/lottieitem_capi.cpp @@ -88,7 +88,7 @@ void renderer::Layer::buildLayerNode() mCApiData = std::make_unique(); clayer().keypath = name(); } - if (complexContent()) clayer().mAlpha = uchar(combinedAlpha() * 255.f); + if (complexContent()) clayer().mAlpha = uint8_t(combinedAlpha() * 255.f); clayer().mVisible = visible(); // update matte if (hasMatte()) { @@ -124,7 +124,7 @@ void renderer::Layer::buildLayerNode() cNode.mPath.ptCount = 2 * pts.size(); cNode.mPath.elmPtr = elmPtr; cNode.mPath.elmCount = elm.size(); - cNode.mAlpha = uchar(mask.mCombinedAlpha * 255.0f); + cNode.mAlpha = uint8_t(mask.mCombinedAlpha * 255.0f); switch (mask.maskMode()) { case model::Mask::Mode::Add: cNode.mMode = MaskAdd; @@ -196,7 +196,7 @@ void renderer::ImageLayer::buildLayerNode() // Alpha calculation already combined. lotDrawable->mCNode->mImageInfo.mAlpha = - uchar(lotDrawable->mBrush.mTexture->mAlpha); + uint8_t(lotDrawable->mBrush.mTexture->mAlpha); cnodes().push_back(lotDrawable->mCNode.get()); } @@ -216,7 +216,7 @@ static void updateGStops(LOTNode *n, const VGradient *grad) LOTGradientStop *ptr = n->mGradient.stopPtr; for (const auto &i : grad->mStops) { ptr->pos = i.first; - ptr->a = uchar(i.second.alpha() * grad->alpha()); + ptr->a = uint8_t(i.second.alpha() * grad->alpha()); ptr->r = i.second.red(); ptr->g = i.second.green(); ptr->b = i.second.blue(); diff --git a/src/lottie/lottiekeypath.cpp b/src/lottie/lottiekeypath.cpp index e8b6c6ae..21b01aac 100644 --- a/src/lottie/lottiekeypath.cpp +++ b/src/lottie/lottiekeypath.cpp @@ -12,7 +12,7 @@ LOTKeyPath::LOTKeyPath(const std::string &keyPath) } } -bool LOTKeyPath::matches(const std::string &key, uint depth) +bool LOTKeyPath::matches(const std::string &key, uint32_t depth) { if (skip(key)) { // This is an object we programatically create. @@ -28,7 +28,7 @@ bool LOTKeyPath::matches(const std::string &key, uint depth) return false; } -uint LOTKeyPath::nextDepth(const std::string key, uint depth) +uint32_t LOTKeyPath::nextDepth(const std::string key, uint32_t depth) { if (skip(key)) { // If it's a container then we added programatically and it isn't a part @@ -51,7 +51,7 @@ uint LOTKeyPath::nextDepth(const std::string key, uint depth) return depth; } -bool LOTKeyPath::fullyResolvesTo(const std::string key, uint depth) +bool LOTKeyPath::fullyResolvesTo(const std::string key, uint32_t depth) { if (depth > mKeys.size()) { return false; diff --git a/src/lottie/lottiekeypath.h b/src/lottie/lottiekeypath.h index 0b59b161..2c53287e 100644 --- a/src/lottie/lottiekeypath.h +++ b/src/lottie/lottiekeypath.h @@ -30,19 +30,19 @@ class LOTKeyPath { public: LOTKeyPath(const std::string &keyPath); - bool matches(const std::string &key, uint depth); - uint nextDepth(const std::string key, uint depth); - bool fullyResolvesTo(const std::string key, uint depth); + bool matches(const std::string &key, uint32_t depth); + uint32_t nextDepth(const std::string key, uint32_t depth); + bool fullyResolvesTo(const std::string key, uint32_t depth); - bool propagate(const std::string key, uint depth) + bool propagate(const std::string key, uint32_t depth) { return skip(key) ? true : (depth < size()) || (mKeys[depth] == "**"); } bool skip(const std::string &key) const { return key == "__"; } private: - bool isGlobstar(uint depth) const { return mKeys[depth] == "**"; } - bool isGlob(uint depth) const { return mKeys[depth] == "*"; } + bool isGlobstar(uint32_t depth) const { return mKeys[depth] == "**"; } + bool isGlob(uint32_t depth) const { return mKeys[depth] == "*"; } bool endsWithGlobstar() const { return mKeys.back() == "**"; } size_t size() const { return mKeys.size() - 1; } diff --git a/src/lottie/lottiemodel.cpp b/src/lottie/lottiemodel.cpp index 9da82f70..1bca99d2 100644 --- a/src/lottie/lottiemodel.cpp +++ b/src/lottie/lottiemodel.cpp @@ -256,52 +256,12 @@ void model::Gradient::populate(VGradientStops &stops, int frameNo) auto opacityArraySize = size - colorPoints * 4; float *opacityPtr = ptr + (colorPoints * 4); stops.clear(); - size_t j = 0; for (int i = 0; i < colorPoints; i++) { float colorStop = ptr[0]; model::Color color = model::Color(ptr[1], ptr[2], ptr[3]); if (opacityArraySize) { - if (j == opacityArraySize) { - // already reached the end - float stop1 = opacityPtr[j - 4]; - float op1 = opacityPtr[j - 3]; - float stop2 = opacityPtr[j - 2]; - float op2 = opacityPtr[j - 1]; - if (colorStop > stop2) { - stops.push_back( - std::make_pair(colorStop, color.toColor(op2))); - } else { - float progress = (colorStop - stop1) / (stop2 - stop1); - float opacity = op1 + progress * (op2 - op1); - stops.push_back( - std::make_pair(colorStop, color.toColor(opacity))); - } - continue; - } - for (; j < opacityArraySize; j += 2) { - float opacityStop = opacityPtr[j]; - if (opacityStop < colorStop) { - // add a color using opacity stop - stops.push_back(std::make_pair( - opacityStop, color.toColor(opacityPtr[j + 1]))); - continue; - } - // add a color using color stop - if (j == 0) { - stops.push_back(std::make_pair( - colorStop, color.toColor(opacityPtr[j + 1]))); - } else { - float progress = (colorStop - opacityPtr[j - 2]) / - (opacityPtr[j] - opacityPtr[j - 2]); - float opacity = - opacityPtr[j - 1] + - progress * (opacityPtr[j + 1] - opacityPtr[j - 1]); - stops.push_back( - std::make_pair(colorStop, color.toColor(opacity))); - } - j += 2; - break; - } + float opacity = getOpacityAtPosition(opacityPtr, opacityArraySize, colorStop); + stops.push_back(std::make_pair(colorStop, color.toColor(opacity))); } else { stops.push_back(std::make_pair(colorStop, color.toColor())); } @@ -309,6 +269,21 @@ void model::Gradient::populate(VGradientStops &stops, int frameNo) } } +float model::Gradient::getOpacityAtPosition(float *opacities, size_t opacityArraySize, float position) +{ + for (size_t i = 2; i < opacityArraySize; i += 2) + { + float lastPosition = opacities[i - 2]; + float thisPosition = opacities[i]; + if (opacities[i] >= position) { + float progress = (position - lastPosition) / (thisPosition - lastPosition); + progress = progress < 0.0f ? 0.0f : 1.0f < progress ? 1.0f : progress; //clamp(progress, 0, 1) + return opacities[i - 1] + progress * (opacities[i + 1] - opacities[i - 1]); + } + } + return 0.0f; +} + void model::Gradient::update(std::unique_ptr &grad, int frameNo) { bool init = false; diff --git a/src/lottie/lottiemodel.h b/src/lottie/lottiemodel.h index c6b8cf6d..3e043085 100644 --- a/src/lottie/lottiemodel.h +++ b/src/lottie/lottiemodel.h @@ -57,9 +57,9 @@ inline T lerp(const T &start, const T &end, float t) namespace model { -enum class MatteType : uchar { None = 0, Alpha = 1, AlphaInv, Luma, LumaInv }; +enum class MatteType : uint8_t { None = 0, Alpha = 1, AlphaInv, Luma, LumaInv }; -enum class BlendMode : uchar { +enum class BlendMode : uint8_t { Normal = 0, Multiply = 1, Screen = 2, @@ -72,8 +72,8 @@ class Color { Color(float red, float green, float blue) : r(red), g(green), b(blue) {} VColor toColor(float a = 1) { - return VColor(uchar(255 * r), uchar(255 * g), uchar(255 * b), - uchar(255 * a)); + return VColor(uint8_t(255 * r), uint8_t(255 * g), uint8_t(255 * b), + uint8_t(255 * a)); } friend inline Color operator+(const Color &c1, const Color &c2); friend inline Color operator-(const Color &c1, const Color &c2); @@ -667,7 +667,7 @@ class Group : public Object { class Layer : public Group { public: - enum class Type : uchar { + enum class Type : uint8_t { Precomp = 0, Solid = 1, Image = 2, @@ -821,6 +821,7 @@ class Gradient : public Object { private: void populate(VGradientStops &stops, int frameNo); + float getOpacityAtPosition(float *opacities, size_t opacityArraySize, float position); public: int mGradientType{1}; /* "t" Linear=1 , Radial = 2*/ diff --git a/src/vector/vbitmap.cpp b/src/vector/vbitmap.cpp index 22cb2434..378db227 100644 --- a/src/vector/vbitmap.cpp +++ b/src/vector/vbitmap.cpp @@ -31,31 +31,31 @@ V_BEGIN_NAMESPACE void VBitmap::Impl::reset(size_t width, size_t height, VBitmap::Format format) { mRoData = nullptr; - mWidth = uint(width); - mHeight = uint(height); + mWidth = uint32_t(width); + mHeight = uint32_t(height); mFormat = format; mDepth = depth(format); mStride = ((mWidth * mDepth + 31) >> 5) << 2; // bytes per scanline (must be multiple of 4) - mOwnData = std::make_unique(mStride * mHeight); + mOwnData = std::make_unique(mStride * mHeight); } -void VBitmap::Impl::reset(uchar *data, size_t width, size_t height, size_t bytesPerLine, - VBitmap::Format format) +void VBitmap::Impl::reset(uint8_t *data, size_t width, size_t height, + size_t bytesPerLine, VBitmap::Format format) { mRoData = data; - mWidth = uint(width); - mHeight = uint(height); - mStride = uint(bytesPerLine); + mWidth = uint32_t(width); + mHeight = uint32_t(height); + mStride = uint32_t(bytesPerLine); mFormat = format; mDepth = depth(format); mOwnData = nullptr; } -uchar VBitmap::Impl::depth(VBitmap::Format format) +uint8_t VBitmap::Impl::depth(VBitmap::Format format) { - uchar depth = 1; + uint8_t depth = 1; switch (format) { case VBitmap::Format::Alpha8: depth = 8; @@ -70,7 +70,7 @@ uchar VBitmap::Impl::depth(VBitmap::Format format) return depth; } -void VBitmap::Impl::fill(uint /*pixel*/) +void VBitmap::Impl::fill(uint32_t /*pixel*/) { //@TODO } @@ -79,9 +79,9 @@ void VBitmap::Impl::updateLuma() { if (mFormat != VBitmap::Format::ARGB32_Premultiplied) return; auto dataPtr = data(); - for (uint col = 0; col < mHeight; col++) { - uint *pixel = (uint *)(dataPtr + mStride * col); - for (uint row = 0; row < mWidth; row++) { + for (uint32_t col = 0; col < mHeight; col++) { + uint32_t *pixel = (uint32_t *)(dataPtr + mStride * col); + for (uint32_t row = 0; row < mWidth; row++) { int alpha = vAlpha(*pixel); if (alpha == 0) { pixel++; @@ -112,8 +112,8 @@ VBitmap::VBitmap(size_t width, size_t height, VBitmap::Format format) mImpl = rc_ptr(width, height, format); } -VBitmap::VBitmap(uchar *data, size_t width, size_t height, size_t bytesPerLine, - VBitmap::Format format) +VBitmap::VBitmap(uint8_t *data, size_t width, size_t height, + size_t bytesPerLine, VBitmap::Format format) { if (!data || width <= 0 || height <= 0 || bytesPerLine <= 0 || format == Format::Invalid) @@ -122,7 +122,7 @@ VBitmap::VBitmap(uchar *data, size_t width, size_t height, size_t bytesPerLine, mImpl = rc_ptr(data, width, height, bytesPerLine, format); } -void VBitmap::reset(uchar *data, size_t w, size_t h, size_t bytesPerLine, +void VBitmap::reset(uint8_t *data, size_t w, size_t h, size_t bytesPerLine, VBitmap::Format format) { if (mImpl) { @@ -165,12 +165,12 @@ size_t VBitmap::depth() const return mImpl ? mImpl->mDepth : 0; } -uchar *VBitmap::data() +uint8_t *VBitmap::data() { return mImpl ? mImpl->data() : nullptr; } -uchar *VBitmap::data() const +uint8_t *VBitmap::data() const { return mImpl ? mImpl->data() : nullptr; } @@ -195,7 +195,7 @@ VBitmap::Format VBitmap::format() const return mImpl ? mImpl->format() : VBitmap::Format::Invalid; } -void VBitmap::fill(uint pixel) +void VBitmap::fill(uint32_t pixel) { if (mImpl) mImpl->fill(pixel); } diff --git a/src/vector/vbitmap.h b/src/vector/vbitmap.h index a068d744..bc5059a7 100644 --- a/src/vector/vbitmap.h +++ b/src/vector/vbitmap.h @@ -30,7 +30,7 @@ V_BEGIN_NAMESPACE class VBitmap { public: - enum class Format: uchar { + enum class Format : uint8_t { Invalid, Alpha8, ARGB32, @@ -39,8 +39,10 @@ class VBitmap { VBitmap() = default; VBitmap(size_t w, size_t h, VBitmap::Format format); - VBitmap(uchar *data, size_t w, size_t h, size_t bytesPerLine, VBitmap::Format format); - void reset(uchar *data, size_t w, size_t h, size_t stride, VBitmap::Format format); + VBitmap(uint8_t *data, size_t w, size_t h, size_t bytesPerLine, + VBitmap::Format format); + void reset(uint8_t *data, size_t w, size_t h, size_t stride, + VBitmap::Format format); void reset(size_t w, size_t h, VBitmap::Format format=Format::ARGB32_Premultiplied); size_t stride() const; size_t width() const; @@ -48,27 +50,28 @@ class VBitmap { size_t depth() const; VBitmap::Format format() const; bool valid() const; - uchar * data(); - uchar * data() const; + uint8_t * data(); + uint8_t * data() const; VRect rect() const; VSize size() const; - void fill(uint pixel); + void fill(uint32_t pixel); void updateLuma(); private: struct Impl { - std::unique_ptr mOwnData{nullptr}; - uchar * mRoData{nullptr}; - uint mWidth{0}; - uint mHeight{0}; - uint mStride{0}; - uchar mDepth{0}; + std::unique_ptr mOwnData{nullptr}; + uint8_t * mRoData{nullptr}; + uint32_t mWidth{0}; + uint32_t mHeight{0}; + uint32_t mStride{0}; + uint8_t mDepth{0}; VBitmap::Format mFormat{VBitmap::Format::Invalid}; explicit Impl(size_t width, size_t height, VBitmap::Format format) { reset(width, height, format); } - explicit Impl(uchar *data, size_t w, size_t h, size_t bytesPerLine, VBitmap::Format format) + explicit Impl(uint8_t *data, size_t w, size_t h, size_t bytesPerLine, + VBitmap::Format format) { reset(data, w, h, bytesPerLine, format); } @@ -77,12 +80,12 @@ class VBitmap { size_t stride() const { return mStride; } size_t width() const { return mWidth; } size_t height() const { return mHeight; } - uchar * data() { return mRoData ? mRoData : mOwnData.get(); } + uint8_t * data() { return mRoData ? mRoData : mOwnData.get(); } VBitmap::Format format() const { return mFormat; } - void reset(uchar *, size_t, size_t, size_t, VBitmap::Format); + void reset(uint8_t *, size_t, size_t, size_t, VBitmap::Format); void reset(size_t, size_t, VBitmap::Format); - static uchar depth(VBitmap::Format format); - void fill(uint); + static uint8_t depth(VBitmap::Format format); + void fill(uint32_t); void updateLuma(); }; diff --git a/src/vector/vbrush.cpp b/src/vector/vbrush.cpp index fc0902ba..f2ab3387 100644 --- a/src/vector/vbrush.cpp +++ b/src/vector/vbrush.cpp @@ -43,7 +43,7 @@ VBrush::VBrush(const VColor &color) : mType(VBrush::Type::Solid), mColor(color) { } -VBrush::VBrush(uchar r, uchar g, uchar b, uchar a) +VBrush::VBrush(uint8_t r, uint8_t g, uint8_t b, uint8_t a) : mType(VBrush::Type::Solid), mColor(r, g, b, a) { diff --git a/src/vector/vbrush.h b/src/vector/vbrush.h index 74f8dcaf..a1abbd34 100644 --- a/src/vector/vbrush.h +++ b/src/vector/vbrush.h @@ -75,7 +75,7 @@ class VBrush { VBrush():mType(Type::NoBrush),mColor(){}; explicit VBrush(const VColor &color); explicit VBrush(const VGradient *gradient); - explicit VBrush(uchar r, uchar g, uchar b, uchar a); + explicit VBrush(uint8_t r, uint8_t g, uint8_t b, uint8_t a); explicit VBrush(const VTexture *texture); inline VBrush::Type type() const { return mType; } public: diff --git a/src/vector/vdrawable.cpp b/src/vector/vdrawable.cpp index c8ff02bc..55b1bc84 100644 --- a/src/vector/vdrawable.cpp +++ b/src/vector/vdrawable.cpp @@ -106,7 +106,7 @@ void VDrawable::setDashInfo(std::vector &dashInfo) bool hasChanged = false; if (obj->mDash.size() == dashInfo.size()) { - for (uint i = 0; i < dashInfo.size(); ++i) { + for (uint32_t i = 0; i < dashInfo.size(); ++i) { if (!vCompare(obj->mDash[i], dashInfo[i])) { hasChanged = true; break; diff --git a/src/vector/vdrawhelper.cpp b/src/vector/vdrawhelper.cpp index b14146d3..6117a0a3 100644 --- a/src/vector/vdrawhelper.cpp +++ b/src/vector/vdrawhelper.cpp @@ -56,7 +56,7 @@ class VGradientCache { VCacheKey hash_val = 0; VCacheData info; const VGradientStops &stops = gradient.mStops; - for (uint i = 0; i < stops.size() && i <= 2; i++) + for (uint32_t i = 0; i < stops.size() && i <= 2; i++) hash_val += VCacheKey(stops[i].second.premulARGB() * gradient.alpha()); @@ -100,11 +100,11 @@ class VGradientCache { } protected: - uint maxCacheSize() const { return 60; } + uint32_t maxCacheSize() const { return 60; } VCacheData addCacheElement(VCacheKey hash_val, const VGradient &gradient) { if (mCache.size() == maxCacheSize()) { - uint count = maxCacheSize() / 10; + uint32_t count = maxCacheSize() / 10; while (count--) { mCache.erase(mCache.begin()); } @@ -519,7 +519,7 @@ static void blend_color(size_t size, const VRle::Span *array, void *userData) { VSpanData *data = (VSpanData *)(userData); Operator op = getOperator(data); - const uint color = data->mSolid; + const uint32_t color = data->mSolid; for (size_t i = 0 ; i < size; ++i) { const auto &span = array[i]; @@ -528,12 +528,12 @@ static void blend_color(size_t size, const VRle::Span *array, void *userData) } // Signature of Process Object -// void Pocess(uint* scratchBuffer, size_t x, size_t y, uchar cov) +// void Pocess(uint* scratchBuffer, size_t x, size_t y, uint8_t cov) template static inline void process_in_chunk(const VRle::Span *array, size_t size, Process process) { - std::array buf; + std::array buf; for (size_t i = 0; i < size; i++) { const auto &span = array[i]; size_t len = span.len; @@ -557,7 +557,7 @@ static void blend_gradient(size_t size, const VRle::Span *array, process_in_chunk( array, size, - [&](uint *scratch, size_t x, size_t y, size_t len, uchar cov) { + [&](uint32_t *scratch, size_t x, size_t y, size_t len, uint8_t cov) { op.srcFetch(scratch, &op, data, (int)y, (int)x, (int)len); op.func(data->buffer((int)x, (int)y), (int)len, scratch, cov); }); @@ -569,7 +569,7 @@ constexpr const T &clamp(const T &v, const T &lo, const T &hi) return v < lo ? lo : hi < v ? hi : v; } -static constexpr inline uchar alpha_mul(uchar a, uchar b) +static constexpr inline uint8_t alpha_mul(uint8_t a, uint8_t b) { return ((a * b) >> 8); } @@ -590,7 +590,7 @@ static void blend_image_xform(size_t size, const VRle::Span *array, process_in_chunk( array, size, - [&](uint *scratch, size_t x, size_t y, size_t len, uchar cov) { + [&](uint32_t *scratch, size_t x, size_t y, size_t len, uint8_t cov) { const auto coverage = (cov * src.alpha()) >> 8; const float xfactor = y * data->m21 + data->dx + data->m11; const float yfactor = y * data->m22 + data->dy + data->m12; diff --git a/src/vector/vdrawhelper.h b/src/vector/vdrawhelper.h index e654e93b..7d31e3f3 100644 --- a/src/vector/vdrawhelper.h +++ b/src/vector/vdrawhelper.h @@ -127,7 +127,7 @@ class VRasterBuffer { void resetBuffer(int val = 0); - inline uchar *scanLine(int y) + inline uint8_t *scanLine(int y) { assert(y >= 0); assert(size_t(y) < mHeight); @@ -150,7 +150,7 @@ class VRasterBuffer { size_t mHeight{0}; size_t mBytesPerLine{0}; size_t mBytesPerPixel{0}; - mutable uchar * mBuffer{nullptr}; + mutable uint8_t *mBuffer{nullptr}; }; struct VGradientData { @@ -171,8 +171,8 @@ struct VGradientData { struct VTextureData : public VRasterBuffer { uint32_t pixel(int x, int y) const { return *pixelRef(x, y); }; - uchar alpha() const { return mAlpha; } - void setAlpha(uchar alpha) { mAlpha = alpha; } + uint8_t alpha() const { return mAlpha; } + void setAlpha(uint8_t alpha) { mAlpha = alpha; } void setClip(const VRect &clip); // clip rect int left; @@ -180,7 +180,7 @@ struct VTextureData : public VRasterBuffer { int top; int bottom; bool hasAlpha; - uchar mAlpha; + uint8_t mAlpha; }; struct VColorTable { @@ -208,7 +208,7 @@ struct VSpanData { mDrawableSize = VSize(region.width(), region.height()); } - uint *buffer(int x, int y) const + uint32_t *buffer(int x, int y) const { return mRasterBuffer->pixelRef(x + mOffset.x(), y + mOffset.y()); } @@ -256,9 +256,10 @@ inline constexpr int vAlpha(uint32_t c) return c >> 24; } -static inline uint32_t interpolate_pixel(uint x, uint a, uint y, uint b) +static inline uint32_t interpolate_pixel(uint32_t x, uint32_t a, uint32_t y, + uint32_t b) { - uint t = (x & 0xff00ff) * a + (y & 0xff00ff) * b; + uint32_t t = (x & 0xff00ff) * a + (y & 0xff00ff) * b; t >>= 8; t &= 0xff00ff; x = ((x >> 8) & 0xff00ff) * a + ((y >> 8) & 0xff00ff) * b; diff --git a/src/vector/vdrawhelper_common.cpp b/src/vector/vdrawhelper_common.cpp index b2eb6db0..8a91b0f3 100644 --- a/src/vector/vdrawhelper_common.cpp +++ b/src/vector/vdrawhelper_common.cpp @@ -65,10 +65,10 @@ static void color_SourceOver(uint32_t *dest, int length, uint32_t color, dest = d * sa * ca + d * cia = d * (sa * ca + cia) */ -static void color_DestinationIn(uint *dest, int length, uint color, - uint alpha) +static void color_DestinationIn(uint32_t *dest, int length, uint32_t color, + uint32_t alpha) { - uint a = vAlpha(color); + uint32_t a = vAlpha(color); if (alpha != 255) { a = BYTE_MUL(a, alpha) + 255 - alpha; } @@ -82,10 +82,10 @@ static void color_DestinationIn(uint *dest, int length, uint color, dest = d * sia * ca + d * cia = d * (sia * ca + cia) */ -static void color_DestinationOut(uint *dest, int length, uint color, - uint alpha) +static void color_DestinationOut(uint32_t *dest, int length, uint32_t color, + uint32_t alpha) { - uint a = vAlpha(~color); + uint32_t a = vAlpha(~color); if (alpha != 255) a = BYTE_MUL(a, alpha) + 255 - alpha; for (int i = 0; i < length; ++i) { dest[i] = BYTE_MUL(dest[i], a); @@ -96,9 +96,9 @@ static void src_Source(uint32_t *dest, int length, const uint32_t *src, uint32_t alpha) { if (alpha == 255) { - memcpy(dest, src, size_t(length) * sizeof(uint)); + memcpy(dest, src, size_t(length) * sizeof(uint32_t)); } else { - uint ialpha = 255 - alpha; + uint32_t ialpha = 255 - alpha; for (int i = 0; i < length; ++i) { dest[i] = interpolate_pixel(src[i], alpha, dest[i], ialpha); @@ -112,7 +112,7 @@ static void src_Source(uint32_t *dest, int length, const uint32_t *src, static void src_SourceOver(uint32_t *dest, int length, const uint32_t *src, uint32_t alpha) { - uint s, sia; + uint32_t s, sia; if (alpha == 255) { for (int i = 0; i < length; ++i) { @@ -136,33 +136,33 @@ static void src_SourceOver(uint32_t *dest, int length, const uint32_t *src, } } -static void src_DestinationIn(uint *dest, int length, const uint *src, - uint alpha) +static void src_DestinationIn(uint32_t *dest, int length, const uint32_t *src, + uint32_t alpha) { if (alpha == 255) { for (int i = 0; i < length; ++i) { dest[i] = BYTE_MUL(dest[i], vAlpha(src[i])); } } else { - uint cia = 255 - alpha; + uint32_t cia = 255 - alpha; for (int i = 0; i < length; ++i) { - uint a = BYTE_MUL(vAlpha(src[i]), alpha) + cia; + uint32_t a = BYTE_MUL(vAlpha(src[i]), alpha) + cia; dest[i] = BYTE_MUL(dest[i], a); } } } -static void src_DestinationOut(uint *dest, int length, const uint *src, - uint alpha) +static void src_DestinationOut(uint32_t *dest, int length, const uint32_t *src, + uint32_t alpha) { if (alpha == 255) { for (int i = 0; i < length; ++i) { dest[i] = BYTE_MUL(dest[i], vAlpha(~src[i])); } } else { - uint cia = 255 - alpha; + uint32_t cia = 255 - alpha; for (int i = 0; i < length; ++i) { - uint sia = BYTE_MUL(vAlpha(~src[i]), alpha) + cia; + uint32_t sia = BYTE_MUL(vAlpha(~src[i]), alpha) + cia; dest[i] = BYTE_MUL(dest[i], sia); } } diff --git a/src/vector/vglobal.h b/src/vector/vglobal.h index 45e95e33..0aad7e8c 100644 --- a/src/vector/vglobal.h +++ b/src/vector/vglobal.h @@ -29,9 +29,6 @@ #include #include -using uint = uint32_t; -using ushort = uint16_t; -using uchar = uint8_t; #if !defined(V_NAMESPACE) @@ -122,10 +119,13 @@ class vFlagHelper { explicit constexpr inline vFlagHelper(int ai) noexcept : i(ai) {} constexpr inline operator int() const noexcept { return i; } - explicit constexpr inline vFlagHelper(uint ai) noexcept : i(int(ai)) {} + explicit constexpr inline vFlagHelper(uint32_t ai) noexcept : i(int(ai)) {} explicit constexpr inline vFlagHelper(short ai) noexcept : i(int(ai)) {} - explicit constexpr inline vFlagHelper(ushort ai) noexcept : i(int(uint(ai))) {} - constexpr inline operator uint() const noexcept { return uint(i); } + explicit constexpr inline vFlagHelper(uint16_t ai) noexcept + : i(int(uint32_t(ai))) + { + } + constexpr inline operator uint32_t() const noexcept { return uint32_t(i); } }; template @@ -139,7 +139,7 @@ class vFlag { using Int = typename std::conditional< std::is_unsigned::type>::value, - unsigned int, signed int>::type; + uint32_t, signed int>::type; using enum_type = Enum; // compiler-generated copy/move ctor/assignment operators are fine! @@ -153,7 +153,7 @@ class vFlag { i &= mask; return *this; } - inline vFlag &operator&=(uint mask) noexcept + inline vFlag &operator&=(uint32_t mask) noexcept { i &= mask; return *this; @@ -206,7 +206,7 @@ class vFlag { { return vFlag(vFlagHelper(i & mask)); } - constexpr inline vFlag operator&(uint mask) const noexcept + constexpr inline vFlag operator&(uint32_t mask) const noexcept { return vFlag(vFlagHelper(i & mask)); } @@ -236,44 +236,47 @@ class vFlag { class VColor { public: VColor() = default; - explicit VColor(uchar red, uchar green, uchar blue, uchar alpha = 255) noexcept - :a(alpha), r(red), g(green), b(blue){} - inline uchar red() const noexcept { return r; } - inline uchar green() const noexcept { return g; } - inline uchar blue() const noexcept { return b; } - inline uchar alpha() const noexcept { return a; } - inline void setRed(uchar red) noexcept { r = red; } - inline void setGreen(uchar green) noexcept { g = green; } - inline void setBlue(uchar blue) noexcept { b = blue; } - inline void setAlpha(uchar alpha) noexcept { a = alpha; } + explicit VColor(uint8_t red, uint8_t green, uint8_t blue, + uint8_t alpha = 255) noexcept + : a(alpha), r(red), g(green), b(blue) + { + } + inline uint8_t red() const noexcept { return r; } + inline uint8_t green() const noexcept { return g; } + inline uint8_t blue() const noexcept { return b; } + inline uint8_t alpha() const noexcept { return a; } + inline void setRed(uint8_t red) noexcept { r = red; } + inline void setGreen(uint8_t green) noexcept { g = green; } + inline void setBlue(uint8_t blue) noexcept { b = blue; } + inline void setAlpha(uint8_t alpha) noexcept { a = alpha; } inline bool isOpaque() const { return a == 255; } inline bool isTransparent() const { return a == 0; } inline bool operator==(const VColor &o) const { return ((a == o.a) && (r == o.r) && (g == o.g) && (b == o.b)); } - uint premulARGB() const + uint32_t premulARGB() const { int pr = (r * a) / 255; int pg = (g * a) / 255; int pb = (b * a) / 255; - return uint((a << 24) | (pr << 16) | (pg << 8) | (pb)); + return uint32_t((a << 24) | (pr << 16) | (pg << 8) | (pb)); } - uint premulARGB(float opacity) const + uint32_t premulARGB(float opacity) const { int alpha = int(a * opacity); int pr = (r * alpha) / 255; int pg = (g * alpha) / 255; int pb = (b * alpha) / 255; - return uint((alpha << 24) | (pr << 16) | (pg << 8) | (pb)); + return uint32_t((alpha << 24) | (pr << 16) | (pg << 8) | (pb)); } public: - uchar a{0}; - uchar r{0}; - uchar g{0}; - uchar b{0}; + uint8_t a{0}; + uint8_t r{0}; + uint8_t g{0}; + uint8_t b{0}; }; enum class FillRule: unsigned char { EvenOdd, Winding }; diff --git a/src/vector/vpainter.cpp b/src/vector/vpainter.cpp index 38a58e04..ab5492c7 100644 --- a/src/vector/vpainter.cpp +++ b/src/vector/vpainter.cpp @@ -66,7 +66,7 @@ static void fillRect(const VRect &r, VSpanData *data) int i = 0; while (i < n) { spans[i].x = short(x1); - spans[i].len = ushort(x2 - x1); + spans[i].len = uint16_t(x2 - x1); spans[i].y = short(y + i); spans[i].coverage = 255; ++i; diff --git a/src/vector/vpath.h b/src/vector/vpath.h index 90c2c3e5..9273cb61 100644 --- a/src/vector/vpath.h +++ b/src/vector/vpath.h @@ -35,7 +35,7 @@ class VPath { public: enum class Direction { CCW, CW }; - enum class Element : uchar { MoveTo, LineTo, CubicTo, Close }; + enum class Element : uint8_t { MoveTo, LineTo, CubicTo, Close }; bool empty() const; bool null() const; void moveTo(const VPointF &p); diff --git a/src/vector/vraster.cpp b/src/vector/vraster.cpp index 06243153..fdf66fb0 100644 --- a/src/vector/vraster.cpp +++ b/src/vector/vraster.cpp @@ -380,7 +380,7 @@ struct VRleTask { outRef.convert(mPath); outRef.convert(mCap, mJoin, mStrokeWidth, mMiterLimit); - uint points, contors; + uint32_t points, contors; SW_FT_Stroker_Set(stroker, outRef.ftWidth, outRef.ftCap, outRef.ftJoin, outRef.ftMiterLimit); @@ -461,20 +461,29 @@ class RleTaskScheduler { for (unsigned n = 0; n != _count; ++n) { _threads.emplace_back([&, n] { run(n); }); } + + IsRunning = true; } public: + static bool IsRunning; + static RleTaskScheduler &instance() { static RleTaskScheduler singleton; return singleton; } - ~RleTaskScheduler() + ~RleTaskScheduler() { stop(); } + + void stop() { - for (auto &e : _q) e.done(); + if (IsRunning) { + IsRunning = false; - for (auto &e : _threads) e.join(); + for (auto &e : _q) e.done(); + for (auto &e : _threads) e.join(); + } } void process(VTask task) @@ -499,12 +508,16 @@ class RleTaskScheduler { SW_FT_Stroker stroker; public: + static bool IsRunning; + static RleTaskScheduler &instance() { static RleTaskScheduler singleton; return singleton; } + void stop() {} + RleTaskScheduler() { SW_FT_Stroker_New(&stroker); } ~RleTaskScheduler() { SW_FT_Stroker_Done(stroker); } @@ -513,6 +526,8 @@ class RleTaskScheduler { }; #endif +bool RleTaskScheduler::IsRunning{false}; + struct VRasterizer::VRasterizerImpl { VRleTask mTask; @@ -560,4 +575,11 @@ void VRasterizer::rasterize(VPath path, CapStyle cap, JoinStyle join, updateRequest(); } +void lottieShutdownRasterTaskScheduler() +{ + if (RleTaskScheduler::IsRunning) { + RleTaskScheduler::instance().stop(); + } +} + V_END_NAMESPACE diff --git a/src/vector/vrle.cpp b/src/vector/vrle.cpp index 051560da..753db1a1 100644 --- a/src/vector/vrle.cpp +++ b/src/vector/vrle.cpp @@ -41,7 +41,7 @@ static size_t _opGeneric(rle_view &a, rle_view &b, Result &result, static size_t _opIntersect(const VRect &, rle_view &, Result &); static size_t _opIntersect(rle_view &, rle_view &, Result &); -static inline uchar divBy255(int x) +static inline uint8_t divBy255(int x) { return (x + (x >> 8) + 0x80) >> 8; } @@ -142,7 +142,7 @@ void VRle::Data::updateBbox() const } } -void VRle::Data::operator*=(uchar alpha) +void VRle::Data::operator*=(uint8_t alpha) { for (auto &i : mSpans) { i.coverage = divBy255(i.coverage * alpha); @@ -425,7 +425,7 @@ static size_t _opIntersect(const VRect &clip, rle_view &obj, Result &result) out->x = minx; } else { out->x = span.x; - out->len = std::min(span.len, ushort(maxx - span.x + 1)); + out->len = std::min(span.len, uint16_t(maxx - span.x + 1)); } if (out->len != 0) { out->y = span.y; @@ -442,12 +442,12 @@ static size_t _opIntersect(const VRect &clip, rle_view &obj, Result &result) return result.max_size() - available; } -static void blitXor(VRle::Span *spans, int count, uchar *buffer, int offsetX) +static void blitXor(VRle::Span *spans, int count, uint8_t *buffer, int offsetX) { while (count--) { int x = spans->x + offsetX; int l = spans->len; - uchar *ptr = buffer + x; + uint8_t *ptr = buffer + x; while (l--) { int da = *ptr; *ptr = divBy255((255 - spans->coverage) * (da) + @@ -458,13 +458,13 @@ static void blitXor(VRle::Span *spans, int count, uchar *buffer, int offsetX) } } -static void blitDestinationOut(VRle::Span *spans, int count, uchar *buffer, +static void blitDestinationOut(VRle::Span *spans, int count, uint8_t *buffer, int offsetX) { while (count--) { int x = spans->x + offsetX; int l = spans->len; - uchar *ptr = buffer + x; + uint8_t *ptr = buffer + x; while (l--) { *ptr = divBy255((255 - spans->coverage) * (*ptr)); ptr++; @@ -473,13 +473,13 @@ static void blitDestinationOut(VRle::Span *spans, int count, uchar *buffer, } } -static void blitSrcOver(VRle::Span *spans, int count, uchar *buffer, +static void blitSrcOver(VRle::Span *spans, int count, uint8_t *buffer, int offsetX) { while (count--) { int x = spans->x + offsetX; int l = spans->len; - uchar *ptr = buffer + x; + uint8_t *ptr = buffer + x; while (l--) { *ptr = spans->coverage + divBy255((255 - spans->coverage) * (*ptr)); ptr++; @@ -488,12 +488,12 @@ static void blitSrcOver(VRle::Span *spans, int count, uchar *buffer, } } -void blitSrc(VRle::Span *spans, int count, uchar *buffer, int offsetX) +void blitSrc(VRle::Span *spans, int count, uint8_t *buffer, int offsetX) { while (count--) { int x = spans->x + offsetX; int l = spans->len; - uchar *ptr = buffer + x; + uint8_t *ptr = buffer + x; while (l--) { *ptr = std::max(spans->coverage, *ptr); ptr++; @@ -502,15 +502,16 @@ void blitSrc(VRle::Span *spans, int count, uchar *buffer, int offsetX) } } -size_t bufferToRle(uchar *buffer, int size, int offsetX, int y, VRle::Span *out) +size_t bufferToRle(uint8_t *buffer, int size, int offsetX, int y, + VRle::Span *out) { size_t count = 0; - uchar value = buffer[0]; + uint8_t value = buffer[0]; int curIndex = 0; // size = offsetX < 0 ? size + offsetX : size; for (int i = 0; i < size; i++) { - uchar curValue = buffer[0]; + uint8_t curValue = buffer[0]; if (value != curValue) { if (value) { out->y = y; @@ -550,10 +551,10 @@ struct SpanMerger { break; } } - using blitter = void (*)(VRle::Span *, int, uchar *, int); + using blitter = void (*)(VRle::Span *, int, uint8_t *, int); blitter _blitter; std::array _result; - std::array _buffer; + std::array _buffer; VRle::Span * _aStart{nullptr}; VRle::Span * _bStart{nullptr}; diff --git a/src/vector/vrle.h b/src/vector/vrle.h index 761e5d1b..1bbb8365 100644 --- a/src/vector/vrle.h +++ b/src/vector/vrle.h @@ -36,8 +36,8 @@ class VRle { struct Span { short x{0}; short y{0}; - ushort len{0}; - uchar coverage{0}; + uint16_t len{0}; + uint8_t coverage{0}; }; using VRleSpanCb = void (*)(size_t count, const VRle::Span *spans, void *userData); @@ -52,7 +52,7 @@ class VRle { void reset() { d.write().reset(); } void translate(const VPoint &p) { d.write().translate(p); } - void operator*=(uchar alpha) { d.write() *= alpha; } + void operator*=(uint8_t alpha) { d.write() *= alpha; } void intersect(const VRect &r, VRleSpanCb cb, void *userData) const; void intersect(const VRle &rle, VRleSpanCb cb, void *userData) const; @@ -91,7 +91,7 @@ class VRle { void setBbox(const VRect &bbox) const; void reset(); void translate(const VPoint &p); - void operator*=(uchar alpha); + void operator*=(uint8_t alpha); void opGeneric(const VRle::Data &, const VRle::Data &, Op code); void opSubstract(const VRle::Data &, const VRle::Data &); void opIntersect(VRle::View a, VRle::View b);