Commit 173d329b authored by salix5's avatar salix5 Committed by GitHub

renormalize newline (#2975)

parent b824c77e
#include "image_resizer.h" #include "image_resizer.h"
#include <cmath> #include <cmath>
#ifdef _OPENMP #ifdef _OPENMP
#include <omp.h> #include <omp.h>
#endif #endif
#define STB_IMAGE_RESIZE2_IMPLEMENTATION #define STB_IMAGE_RESIZE2_IMPLEMENTATION
#include "stb_image_resize2.h" #include "stb_image_resize2.h"
namespace ygo { namespace ygo {
ImageResizer imageResizer; ImageResizer imageResizer;
struct StbSamplerCache { struct StbSamplerCache {
STBIR_RESIZE resize{}; STBIR_RESIZE resize{};
int in_w = 0; int in_w = 0;
int in_h = 0; int in_h = 0;
int out_w = 0; int out_w = 0;
int out_h = 0; int out_h = 0;
stbir_pixel_layout layout = STBIR_BGRA; stbir_pixel_layout layout = STBIR_BGRA;
bool samplers_built = false; bool samplers_built = false;
~StbSamplerCache() { ~StbSamplerCache() {
if(samplers_built) { if(samplers_built) {
stbir_free_samplers(&resize); stbir_free_samplers(&resize);
samplers_built = false; samplers_built = false;
} }
} }
void reset_if_needed(int new_in_w, int new_in_h, int new_out_w, int new_out_h, stbir_pixel_layout new_layout) { void reset_if_needed(int new_in_w, int new_in_h, int new_out_w, int new_out_h, stbir_pixel_layout new_layout) {
if(new_in_w == in_w && new_in_h == in_h && new_out_w == out_w && new_out_h == out_h && new_layout == layout) if(new_in_w == in_w && new_in_h == in_h && new_out_w == out_w && new_out_h == out_h && new_layout == layout)
return; return;
if(samplers_built) { if(samplers_built) {
stbir_free_samplers(&resize); stbir_free_samplers(&resize);
samplers_built = false; samplers_built = false;
} }
in_w = new_in_w; in_w = new_in_w;
in_h = new_in_h; in_h = new_in_h;
out_w = new_out_w; out_w = new_out_w;
out_h = new_out_h; out_h = new_out_h;
layout = new_layout; layout = new_layout;
resize = STBIR_RESIZE{}; resize = STBIR_RESIZE{};
} }
}; };
/** /**
* Scale image using stb_image_resize2. * Scale image using stb_image_resize2.
* Returns true on success, false on failure or unsupported format. * Returns true on success, false on failure or unsupported format.
*/ */
bool ImageResizer::imageScaleSTB(irr::video::IImage* src, irr::video::IImage* dest) { bool ImageResizer::imageScaleSTB(irr::video::IImage* src, irr::video::IImage* dest) {
if(!src || !dest) if(!src || !dest)
return false; return false;
const auto srcDim = src->getDimension(); const auto srcDim = src->getDimension();
const auto destDim = dest->getDimension(); const auto destDim = dest->getDimension();
if(srcDim.Width == 0 || srcDim.Height == 0 || destDim.Width == 0 || destDim.Height == 0) if(srcDim.Width == 0 || srcDim.Height == 0 || destDim.Width == 0 || destDim.Height == 0)
return false; return false;
if(src->getColorFormat() != dest->getColorFormat()) if(src->getColorFormat() != dest->getColorFormat())
return false; return false;
stbir_pixel_layout layout = STBIR_BGRA; stbir_pixel_layout layout = STBIR_BGRA;
// Fast-paths (8-bit per channel only): // Fast-paths (8-bit per channel only):
// - ECF_A8R8G8B8: Irrlicht stores as BGRA in memory on little-endian. // - ECF_A8R8G8B8: Irrlicht stores as BGRA in memory on little-endian.
// - ECF_R8G8B8: common for JPEGs (3 channels). // - ECF_R8G8B8: common for JPEGs (3 channels).
switch(src->getColorFormat()) { switch(src->getColorFormat()) {
case irr::video::ECF_A8R8G8B8: case irr::video::ECF_A8R8G8B8:
layout = STBIR_BGRA; layout = STBIR_BGRA;
break; break;
case irr::video::ECF_R8G8B8: case irr::video::ECF_R8G8B8:
layout = STBIR_RGB; layout = STBIR_RGB;
break; break;
default: default:
return false; return false;
} }
void* srcPtr = src->lock(); void* srcPtr = src->lock();
if(!srcPtr) if(!srcPtr)
return false; return false;
void* destPtr = dest->lock(); void* destPtr = dest->lock();
if(!destPtr) { if(!destPtr) {
src->unlock(); src->unlock();
return false; return false;
} }
const int srcStride = (int)src->getPitch(); const int srcStride = (int)src->getPitch();
const int destStride = (int)dest->getPitch(); const int destStride = (int)dest->getPitch();
thread_local StbSamplerCache cache; thread_local StbSamplerCache cache;
cache.reset_if_needed((int)srcDim.Width, (int)srcDim.Height, (int)destDim.Width, (int)destDim.Height, layout); cache.reset_if_needed((int)srcDim.Width, (int)srcDim.Height, (int)destDim.Width, (int)destDim.Height, layout);
if(!cache.samplers_built) { if(!cache.samplers_built) {
stbir_resize_init(&cache.resize, stbir_resize_init(&cache.resize,
srcPtr, (int)srcDim.Width, (int)srcDim.Height, srcStride, srcPtr, (int)srcDim.Width, (int)srcDim.Height, srcStride,
destPtr, (int)destDim.Width, (int)destDim.Height, destStride, destPtr, (int)destDim.Width, (int)destDim.Height, destStride,
layout, STBIR_TYPE_UINT8); layout, STBIR_TYPE_UINT8);
stbir_set_edgemodes(&cache.resize, STBIR_EDGE_CLAMP, STBIR_EDGE_CLAMP); stbir_set_edgemodes(&cache.resize, STBIR_EDGE_CLAMP, STBIR_EDGE_CLAMP);
// Use box filters to reduce aliasing when downscaling. // Use box filters to reduce aliasing when downscaling.
stbir_set_filters(&cache.resize, STBIR_FILTER_BOX, STBIR_FILTER_BOX); stbir_set_filters(&cache.resize, STBIR_FILTER_BOX, STBIR_FILTER_BOX);
cache.samplers_built = (stbir_build_samplers(&cache.resize) != 0); cache.samplers_built = (stbir_build_samplers(&cache.resize) != 0);
if(!cache.samplers_built) { if(!cache.samplers_built) {
dest->unlock(); dest->unlock();
src->unlock(); src->unlock();
return false; return false;
} }
} else { } else {
// Reuse samplers but update buffer pointers for the current images // Reuse samplers but update buffer pointers for the current images
stbir_set_buffer_ptrs(&cache.resize, srcPtr, srcStride, destPtr, destStride); stbir_set_buffer_ptrs(&cache.resize, srcPtr, srcStride, destPtr, destStride);
} }
const int ok = stbir_resize_extended(&cache.resize); const int ok = stbir_resize_extended(&cache.resize);
dest->unlock(); dest->unlock();
src->unlock(); src->unlock();
return ok != 0; return ok != 0;
} }
/** /**
* Scale image using nearest neighbor anti-aliasing. * Scale image using nearest neighbor anti-aliasing.
* Function by Warr1024, from https://github.com/minetest/minetest/issues/2419, modified. * Function by Warr1024, from https://github.com/minetest/minetest/issues/2419, modified.
*/ */
void ImageResizer::imageScaleNNAA(irr::video::IImage* src, irr::video::IImage* dest, bool use_threading) { void ImageResizer::imageScaleNNAA(irr::video::IImage* src, irr::video::IImage* dest, bool use_threading) {
const auto& srcDim = src->getDimension(); const auto& srcDim = src->getDimension();
const auto& destDim = dest->getDimension(); const auto& destDim = dest->getDimension();
if (destDim.Width == 0 || destDim.Height == 0) if (destDim.Width == 0 || destDim.Height == 0)
return; return;
// Cache scale ratios. // Cache scale ratios.
const double rx = (double)srcDim.Width / destDim.Width; const double rx = (double)srcDim.Width / destDim.Width;
const double ry = (double)srcDim.Height / destDim.Height; const double ry = (double)srcDim.Height / destDim.Height;
#pragma omp parallel if(use_threading) #pragma omp parallel if(use_threading)
{ {
// Walk each destination image pixel. // Walk each destination image pixel.
#pragma omp for schedule(dynamic) #pragma omp for schedule(dynamic)
for(irr::s32 dy = 0; dy < (irr::s32)destDim.Height; dy++) { for(irr::s32 dy = 0; dy < (irr::s32)destDim.Height; dy++) {
for(irr::s32 dx = 0; dx < (irr::s32)destDim.Width; dx++) { for(irr::s32 dx = 0; dx < (irr::s32)destDim.Width; dx++) {
// Calculate floating-point source rectangle bounds. // Calculate floating-point source rectangle bounds.
double minsx = dx * rx; double minsx = dx * rx;
double maxsx = minsx + rx; double maxsx = minsx + rx;
double minsy = dy * ry; double minsy = dy * ry;
double maxsy = minsy + ry; double maxsy = minsy + ry;
irr::u32 sx_begin = (irr::u32)std::floor(minsx); irr::u32 sx_begin = (irr::u32)std::floor(minsx);
irr::u32 sx_end = (irr::u32)std::ceil(maxsx); irr::u32 sx_end = (irr::u32)std::ceil(maxsx);
if (sx_end > srcDim.Width) if (sx_end > srcDim.Width)
sx_end = srcDim.Width; sx_end = srcDim.Width;
irr::u32 sy_begin = (irr::u32)std::floor(minsy); irr::u32 sy_begin = (irr::u32)std::floor(minsy);
irr::u32 sy_end = (irr::u32)std::ceil(maxsy); irr::u32 sy_end = (irr::u32)std::ceil(maxsy);
if (sy_end > srcDim.Height) if (sy_end > srcDim.Height)
sy_end = srcDim.Height; sy_end = srcDim.Height;
// Total area, and integral of r, g, b values over that area, // Total area, and integral of r, g, b values over that area,
// initialized to zero, to be summed up in next loops. // initialized to zero, to be summed up in next loops.
double area = 0, ra = 0, ga = 0, ba = 0, aa = 0; double area = 0, ra = 0, ga = 0, ba = 0, aa = 0;
irr::video::SColor pxl, npxl; irr::video::SColor pxl, npxl;
// Loop over the integral pixel positions described by those bounds. // Loop over the integral pixel positions described by those bounds.
for(irr::u32 sy = sy_begin; sy < sy_end; sy++) { for(irr::u32 sy = sy_begin; sy < sy_end; sy++) {
for(irr::u32 sx = sx_begin; sx < sx_end; sx++) { for(irr::u32 sx = sx_begin; sx < sx_end; sx++) {
// Calculate width, height, then area of dest pixel // Calculate width, height, then area of dest pixel
// that's covered by this source pixel. // that's covered by this source pixel.
double pw = 1; double pw = 1;
if(minsx > sx) if(minsx > sx)
pw += sx - minsx; pw += sx - minsx;
if(maxsx < (sx + 1)) if(maxsx < (sx + 1))
pw += maxsx - sx - 1; pw += maxsx - sx - 1;
double ph = 1; double ph = 1;
if(minsy > sy) if(minsy > sy)
ph += sy - minsy; ph += sy - minsy;
if(maxsy < (sy + 1)) if(maxsy < (sy + 1))
ph += maxsy - sy - 1; ph += maxsy - sy - 1;
double pa = pw * ph; double pa = pw * ph;
// Get source pixel and add it to totals, weighted // Get source pixel and add it to totals, weighted
// by covered area and alpha. // by covered area and alpha.
pxl = src->getPixel(sx, sy); pxl = src->getPixel(sx, sy);
area += pa; area += pa;
ra += pa * pxl.getRed(); ra += pa * pxl.getRed();
ga += pa * pxl.getGreen(); ga += pa * pxl.getGreen();
ba += pa * pxl.getBlue(); ba += pa * pxl.getBlue();
aa += pa * pxl.getAlpha(); aa += pa * pxl.getAlpha();
} }
} }
// Set the destination image pixel to the average color. // Set the destination image pixel to the average color.
if(area > 0) { if(area > 0) {
npxl.set((irr::u32)(aa / area + 0.5), npxl.set((irr::u32)(aa / area + 0.5),
(irr::u32)(ra / area + 0.5), (irr::u32)(ra / area + 0.5),
(irr::u32)(ga / area + 0.5), (irr::u32)(ga / area + 0.5),
(irr::u32)(ba / area + 0.5)); (irr::u32)(ba / area + 0.5));
} else { } else {
npxl.set(0); npxl.set(0);
} }
dest->setPixel(dx, dy, npxl); dest->setPixel(dx, dy, npxl);
} }
} }
} // end of parallel region } // end of parallel region
} }
void ImageResizer::resize(irr::video::IImage* src, irr::video::IImage* dest, bool use_threading) { void ImageResizer::resize(irr::video::IImage* src, irr::video::IImage* dest, bool use_threading) {
if(imageScaleSTB(src, dest)) if(imageScaleSTB(src, dest))
return; return;
imageScaleNNAA(src, dest, use_threading); imageScaleNNAA(src, dest, use_threading);
} }
} // namespace ygo } // namespace ygo
#ifndef IMAGE_RESIZER_H #ifndef IMAGE_RESIZER_H
#define IMAGE_RESIZER_H #define IMAGE_RESIZER_H
#include <irrlicht.h> #include <irrlicht.h>
namespace ygo { namespace ygo {
class ImageResizer { class ImageResizer {
private: private:
bool imageScaleSTB(irr::video::IImage* src, irr::video::IImage* dest); bool imageScaleSTB(irr::video::IImage* src, irr::video::IImage* dest);
void imageScaleNNAA(irr::video::IImage* src, irr::video::IImage* dest, bool use_threading); void imageScaleNNAA(irr::video::IImage* src, irr::video::IImage* dest, bool use_threading);
public: public:
void resize(irr::video::IImage* src, irr::video::IImage* dest, bool use_threading); void resize(irr::video::IImage* src, irr::video::IImage* dest, bool use_threading);
}; };
extern ImageResizer imageResizer; extern ImageResizer imageResizer;
} // namespace ygo } // namespace ygo
#endif // IMAGE_RESIZER_H #endif // IMAGE_RESIZER_H
/**************************************************************************** /****************************************************************************
* *
* ft2build.h * ft2build.h
* *
* FreeType 2 build and setup macros. * FreeType 2 build and setup macros.
* *
* Use custom/ft2build.h instead of the default include/freetype/ft2build.h * Use custom/ft2build.h instead of the default include/freetype/ft2build.h
* to customize the FreeType 2 build of YGOPro. * to customize the FreeType 2 build of YGOPro.
* *
*/ */
#ifndef FT2_BUILD_MY_PLATFORM_H_ #ifndef FT2_BUILD_MY_PLATFORM_H_
#define FT2_BUILD_MY_PLATFORM_H_ #define FT2_BUILD_MY_PLATFORM_H_
#define FT_CONFIG_OPTIONS_H <ygopro/ftoption.h> #define FT_CONFIG_OPTIONS_H <ygopro/ftoption.h>
#define FT_CONFIG_MODULES_H <ygopro/ftmodule.h> #define FT_CONFIG_MODULES_H <ygopro/ftmodule.h>
#include <freetype/config/ftheader.h> #include <freetype/config/ftheader.h>
#endif /* FT2_BUILD_MY_PLATFORM_H_ */ #endif /* FT2_BUILD_MY_PLATFORM_H_ */
/* /*
* This file registers the FreeType modules compiled into the library. * This file registers the FreeType modules compiled into the library.
* *
* YGOPro only uses modules that are needed for TrueType and OpenType fonts. * YGOPro only uses modules that are needed for TrueType and OpenType fonts.
* *
*/ */
FT_USE_MODULE( FT_Driver_ClassRec, tt_driver_class ) FT_USE_MODULE( FT_Driver_ClassRec, tt_driver_class )
FT_USE_MODULE( FT_Driver_ClassRec, cff_driver_class ) FT_USE_MODULE( FT_Driver_ClassRec, cff_driver_class )
FT_USE_MODULE( FT_Module_Class, psaux_module_class ) FT_USE_MODULE( FT_Module_Class, psaux_module_class )
FT_USE_MODULE( FT_Module_Class, psnames_module_class ) FT_USE_MODULE( FT_Module_Class, psnames_module_class )
FT_USE_MODULE( FT_Module_Class, pshinter_module_class ) FT_USE_MODULE( FT_Module_Class, pshinter_module_class )
FT_USE_MODULE( FT_Module_Class, sfnt_module_class ) FT_USE_MODULE( FT_Module_Class, sfnt_module_class )
FT_USE_MODULE( FT_Renderer_Class, ft_smooth_renderer_class ) FT_USE_MODULE( FT_Renderer_Class, ft_smooth_renderer_class )
/* EOF */ /* EOF */
/**************************************************************************** /****************************************************************************
* *
* ftoption.h * ftoption.h
* *
* User-selectable configuration macros (specification only). * User-selectable configuration macros (specification only).
* *
* This file is customized for YGOPro to include only the necessary * This file is customized for YGOPro to include only the necessary
* configuration options for the TrueType and OpenType font driver. * configuration options for the TrueType and OpenType font driver.
* *
* See the original FreeType source code for more information. * See the original FreeType source code for more information.
* /include/freetype/config/ftoption.h * /include/freetype/config/ftoption.h
* *
*/ */
#ifndef FTOPTION_H_ #ifndef FTOPTION_H_
#define FTOPTION_H_ #define FTOPTION_H_
#include <ft2build.h> #include <ft2build.h>
FT_BEGIN_HEADER FT_BEGIN_HEADER
#define FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES #define FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES
#undef FT_CONFIG_OPTION_FORCE_INT64 #undef FT_CONFIG_OPTION_FORCE_INT64
#define FT_CONFIG_OPTION_INLINE_MULFIX #define FT_CONFIG_OPTION_INLINE_MULFIX
#define FT_CONFIG_OPTION_POSTSCRIPT_NAMES #define FT_CONFIG_OPTION_POSTSCRIPT_NAMES
#define FT_CONFIG_OPTION_INCREMENTAL #define FT_CONFIG_OPTION_INCREMENTAL
#define FT_RENDER_POOL_SIZE 16384L #define FT_RENDER_POOL_SIZE 16384L
#define FT_MAX_MODULES 32 #define FT_MAX_MODULES 32
#undef FT_CONFIG_OPTION_USE_MODULE_ERRORS #undef FT_CONFIG_OPTION_USE_MODULE_ERRORS
#define TT_CONFIG_OPTION_EMBEDDED_BITMAPS #define TT_CONFIG_OPTION_EMBEDDED_BITMAPS
#define TT_CONFIG_OPTION_COLOR_LAYERS #define TT_CONFIG_OPTION_COLOR_LAYERS
#define TT_CONFIG_OPTION_POSTSCRIPT_NAMES #define TT_CONFIG_OPTION_POSTSCRIPT_NAMES
#define TT_CONFIG_CMAP_FORMAT_0 #define TT_CONFIG_CMAP_FORMAT_0
#define TT_CONFIG_CMAP_FORMAT_2 #define TT_CONFIG_CMAP_FORMAT_2
#define TT_CONFIG_CMAP_FORMAT_4 #define TT_CONFIG_CMAP_FORMAT_4
#define TT_CONFIG_CMAP_FORMAT_6 #define TT_CONFIG_CMAP_FORMAT_6
#define TT_CONFIG_CMAP_FORMAT_8 #define TT_CONFIG_CMAP_FORMAT_8
#define TT_CONFIG_CMAP_FORMAT_10 #define TT_CONFIG_CMAP_FORMAT_10
#define TT_CONFIG_CMAP_FORMAT_12 #define TT_CONFIG_CMAP_FORMAT_12
#define TT_CONFIG_CMAP_FORMAT_13 #define TT_CONFIG_CMAP_FORMAT_13
#define TT_CONFIG_CMAP_FORMAT_14 #define TT_CONFIG_CMAP_FORMAT_14
#define TT_CONFIG_OPTION_BYTECODE_INTERPRETER #define TT_CONFIG_OPTION_BYTECODE_INTERPRETER
#define TT_CONFIG_OPTION_SUBPIXEL_HINTING #define TT_CONFIG_OPTION_SUBPIXEL_HINTING
#undef TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED #undef TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED
#ifndef TT_CONFIG_OPTION_MAX_RUNNABLE_OPCODES #ifndef TT_CONFIG_OPTION_MAX_RUNNABLE_OPCODES
#define TT_CONFIG_OPTION_MAX_RUNNABLE_OPCODES 1000000L #define TT_CONFIG_OPTION_MAX_RUNNABLE_OPCODES 1000000L
#endif #endif
#define T1_MAX_SUBRS_CALLS 16 #define T1_MAX_SUBRS_CALLS 16
#define T1_MAX_CHARSTRINGS_OPERANDS 256 #define T1_MAX_CHARSTRINGS_OPERANDS 256
#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_X1 500 #define CFF_CONFIG_OPTION_DARKENING_PARAMETER_X1 500
#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y1 400 #define CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y1 400
#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_X2 1000 #define CFF_CONFIG_OPTION_DARKENING_PARAMETER_X2 1000
#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y2 275 #define CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y2 275
#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_X3 1667 #define CFF_CONFIG_OPTION_DARKENING_PARAMETER_X3 1667
#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y3 275 #define CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y3 275
#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_X4 2333 #define CFF_CONFIG_OPTION_DARKENING_PARAMETER_X4 2333
#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y4 0 #define CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y4 0
#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
#define TT_USE_BYTECODE_INTERPRETER #define TT_USE_BYTECODE_INTERPRETER
#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
#define TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL #define TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
#endif #endif
#endif #endif
#ifdef TT_CONFIG_OPTION_COLOR_LAYERS #ifdef TT_CONFIG_OPTION_COLOR_LAYERS
#define TT_SUPPORT_COLRV1 #define TT_SUPPORT_COLRV1
#endif #endif
FT_END_HEADER FT_END_HEADER
#endif /* FTOPTION_H_ */ #endif /* FTOPTION_H_ */
/* END */ /* END */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment