// zlib open source license // // Copyright (c) 2017 to 2019 David Forsgren Piuva // // This software is provided 'as-is', without any express or implied // warranty. In no event will the authors be held liable for any damages // arising from the use of this software. // // Permission is granted to anyone to use this software for any purpose, // including commercial applications, and to alter it and redistribute it // freely, subject to the following restrictions: // // 1. The origin of this software must not be misrepresented; you must not // claim that you wrote the original software. If you use this software // in a product, an acknowledgment in the product documentation would be // appreciated but is not required. // // 2. Altered source versions must be plainly marked as such, and must not be // misrepresented as being the original software. // // 3. This notice may not be removed or altered from any source // distribution. #define DFPSR_INTERNAL_ACCESS #include #include "imageAPI.h" #include "filterAPI.h" #include "../image/draw.h" #include "../image/PackOrder.h" #include "../image/internal/imageTemplate.h" #include "../image/internal/imageInternal.h" using namespace dsr; // -------------------------------- Image generation and filtering -------------------------------- static void mapRgbaU8(ImageRgbaU8Impl& target, const ImageGenRgbaU8& lambda, int startX, int startY) { const int targetWidth = target.width; const int targetHeight = target.height; const int targetStride = target.stride; SafePointer targetRow = imageInternal::getSafeData(target); for (int y = startY; y < targetHeight + startY; y++) { SafePointer targetPixel = targetRow; for (int x = startX; x < targetWidth + startX; x++) { *targetPixel = target.packRgba(lambda(x, y).saturate()); targetPixel += 1; } targetRow.increaseBytes(targetStride); } } void dsr::filter_mapRgbaU8(ImageRgbaU8 target, const ImageGenRgbaU8& lambda, int startX, int startY) { if (target.get() != nullptr) { mapRgbaU8(*target, lambda, startX, startY); } } OrderedImageRgbaU8 dsr::filter_generateRgbaU8(int width, int height, const ImageGenRgbaU8& lambda, int startX, int startY) { OrderedImageRgbaU8 result = image_create_RgbaU8(width, height); filter_mapRgbaU8(result, lambda, startX, startY); return result; } template static void mapMonochrome(IMAGE_TYPE& target, const ImageGenI32& lambda, int startX, int startY) { const int targetWidth = target.width; const int targetHeight = target.height; const int targetStride = target.stride; SafePointer targetRow = imageInternal::getSafeData(target); for (int y = startY; y < targetHeight + startY; y++) { SafePointer targetPixel = targetRow; for (int x = startX; x < targetWidth + startX; x++) { int output = lambda(x, y); if (output < MIN_VALUE) { output = MIN_VALUE; } if (output > MAX_VALUE) { output = MAX_VALUE; } *targetPixel = output; targetPixel += 1; } targetRow.increaseBytes(targetStride); } } void dsr::filter_mapU8(ImageU8 target, const ImageGenI32& lambda, int startX, int startY) { if (target.get() != nullptr) { mapMonochrome(*target, lambda, startX, startY); } } AlignedImageU8 dsr::filter_generateU8(int width, int height, const ImageGenI32& lambda, int startX, int startY) { AlignedImageU8 result = image_create_U8(width, height); filter_mapU8(result, lambda, startX, startY); return result; } void dsr::filter_mapU16(ImageU16 target, const ImageGenI32& lambda, int startX, int startY) { if (target.get() != nullptr) { mapMonochrome(*target, lambda, startX, startY); } } AlignedImageU16 dsr::filter_generateU16(int width, int height, const ImageGenI32& lambda, int startX, int startY) { AlignedImageU16 result = image_create_U16(width, height); filter_mapU16(result, lambda, startX, startY); return result; } static void mapF32(ImageF32Impl& target, const ImageGenF32& lambda, int startX, int startY) { const int targetWidth = target.width; const int targetHeight = target.height; const int targetStride = target.stride; SafePointer targetRow = imageInternal::getSafeData(target); for (int y = startY; y < targetHeight + startY; y++) { SafePointer targetPixel = targetRow; for (int x = startX; x < targetWidth + startX; x++) { *targetPixel = lambda(x, y); targetPixel += 1; } targetRow.increaseBytes(targetStride); } } void dsr::filter_mapF32(ImageF32 target, const ImageGenF32& lambda, int startX, int startY) { if (target.get() != nullptr) { mapF32(*target, lambda, startX, startY); } } AlignedImageF32 dsr::filter_generateF32(int width, int height, const ImageGenF32& lambda, int startX, int startY) { AlignedImageF32 result = image_create_F32(width, height); filter_mapF32(result, lambda, startX, startY); return result; } // -------------------------------- Resize -------------------------------- OrderedImageRgbaU8 dsr::filter_resize(const ImageRgbaU8 &source, Sampler interpolation, int32_t newWidth, int32_t newHeight) { if (source.get() != nullptr) { OrderedImageRgbaU8 resultImage = image_create_RgbaU8(newWidth, newHeight); imageImpl_resizeToTarget(*resultImage, *source, interpolation == Sampler::Linear); return resultImage; } else { return OrderedImageRgbaU8(); // Null gives null } } AlignedImageU8 dsr::filter_resize(const ImageU8 &source, Sampler interpolation, int32_t newWidth, int32_t newHeight) { if (source.get() != nullptr) { AlignedImageU8 resultImage = image_create_U8(newWidth, newHeight); imageImpl_resizeToTarget(*resultImage, *source, interpolation == Sampler::Linear); return resultImage; } else { return AlignedImageU8(); // Null gives null } } void dsr::filter_blockMagnify(ImageRgbaU8 &target, const ImageRgbaU8& source, int pixelWidth, int pixelHeight) { if (target.get() != nullptr && source.get() != nullptr) { imageImpl_blockMagnify(*target, *source, pixelWidth, pixelHeight); } }