<commit_before>#pragma once
#include <cstdint>
#include <depthai-shared/common/optional.hpp>
#include <nlohmann/json.hpp>
#include <vector>

#include "DatatypeEnum.hpp"
#include "RawBuffer.hpp"

namespace dai {

/**
 * Median filter config for disparity post-processing
 */
enum class MedianFilter : int32_t { MEDIAN_OFF = 0, KERNEL_3x3 = 3, KERNEL_5x5 = 5, KERNEL_7x7 = 7 };

/// RawStereoDepthConfig configuration structure
struct RawStereoDepthConfig : public RawBuffer {
    using MedianFilter = dai::MedianFilter;

    struct AlgorithmControl {
        /**
         * Computes and combines disparities in both L-R and R-L directions, and combine them.
         * For better occlusion handling
         */
        bool enableLeftRightCheck = true;

        /**
         * Disparity range increased from 95 to 190, combined from full resolution and downscaled images.
         * Suitable for short range objects
         */
        bool enableExtended = false;

        /**
         * Computes disparity with sub-pixel interpolation (5 fractional bits), suitable for long range
         */
        bool enableSubpixel = false;

        /**
         * Left-right check threshold for left-right, right-left disparity map combine, 0..128
         * Used only when left-right check mode is enabled.
         * Defines the maximum difference between the confidence of pixels from left-right and right-left confidence maps
         */
        std::int32_t leftRightCheckThreshold = 10;

        /**
         * Number of fractional bits for subpixel mode.
         * Valid values: 3,4,5.
         * Defines the number of fractional disparities: 2^x.
         * Median filter postprocessing is supported only for 3 fractional bits.
         */
        std::int32_t subpixelFractionalBits = 3;

        NLOHMANN_DEFINE_TYPE_INTRUSIVE(AlgorithmControl, enableLeftRightCheck, enableExtended, enableSubpixel, leftRightCheckThreshold, subpixelFractionalBits);
    };

    /**
     * Controls the flow of stereo algorithm: left-right check, subpixel etc.
     */
    AlgorithmControl algorithmControl;

    struct PostProcessing {
        /**
         * Set kernel size for disparity/depth median filtering, or disable
         */
        MedianFilter median = MedianFilter::KERNEL_5x5;

        /**
         * Sigma value for bilateral filter. 0 means disabled
         * A larger value of the parameter means that farther colors within the pixel neighborhood will be mixed together.
         */
        std::int16_t bilateralSigmaValue = 0;

        NLOHMANN_DEFINE_TYPE_INTRUSIVE(PostProcessing, median, bilateralSigmaValue);
    };

    /**
     * Controls the postprocessing of disparity and/or depth map.
     */
    PostProcessing postProcessing;

    /**
     * The basic cost function used by the Stereo Accelerator for matching the left and right images is the Census
     * Transform. It works on a block of pixels and computes a bit vector which represents the structure of the
     * image in that block.
     * There are two types of Census Transform based on how the middle pixel is used:
     * Classic Approach and Modified Census. The comparisons that are made between pixels can be or not thresholded.
     * In some cases a mask can be applied to filter out only specific bits from the entire bit stream.
     * All these approaches are:
     * Classic Approach: Uses middle pixel to compare against all its neighbors over a defined window. Each
     * comparison results in a new bit, that is 0 if central pixel is smaller, or 1 if is it bigger than its neighbor.
     * Modified Census Transform: same as classic Census Transform, but instead of comparing central pixel
     * with its neighbors, the window mean will be compared with each pixel over the window.
     * Thresholding Census Transform: same as classic Census Transform, but it is not enough that a
     * neighbor pixel to be bigger than the central pixel, it must be significant bigger (based on a threshold).
     * Census Transform with Mask: same as classic Census Transform, but in this case not all of the pixel from
     * the support window are part of the binary descriptor. We use a ma sk “M” to define which pixels are part
     * of the binary descriptor (1), and which pixels should be skipped (0).
     */
    struct CensusTransform {
        /**
         * Census transform kernel size possible values.
         */
        enum class KernelSize : std::int32_t { AUTO = -1, KERNEL_5x5 = 0, KERNEL_7x7, KERNEL_7x9 };

        /**
         * Census transform kernel size.
         */
        KernelSize kernelSize = KernelSize::AUTO;

        /**
         * Census transform mask, default: auto, mask is set based on resolution and kernel size.
         * Disabled for 400p input resolution.
         * Enabled for 720p.
         * 0XA82415 for 5x5 census transform kernel.
         * 0XAA02A8154055 for 7x7 census transform kernel.
         * 0X2AA00AA805540155 for 7x9 census transform kernel.
         * Empirical values.
         */
        uint64_t kernelMask = 0;

        /**
         * If enabled, each pixel in the window is compared with the mean window value instead of the central pixel.
         */
        bool enableMeanMode = true;

        /**
         * Census transform comparation treshold value.
         */
        uint32_t threshold = 0;

        NLOHMANN_DEFINE_TYPE_INTRUSIVE(CensusTransform, kernelSize, kernelMask, enableMeanMode, threshold);
    };

    /**
     * Census transform settings.
     */
    CensusTransform censusTransform;

    /**
     * The matching cost is way of measuring the similarity of image locations in stereo correspondence
     * algorithm. Based on the configuration parameters and based on the descriptor type, a linear equation
     * is applied to computing the cost for each candidate disparity at each pixel.
     */
    struct CostMatching {
        /**
         * Disparity search range: 64 or 96 pixels are supported by the HW.
         */
        enum class DisparityWidth : std::uint32_t { DISPARITY_64, DISPARITY_96 };

        /**
         * Disparity search range, default 96 pixels.
         */
        DisparityWidth disparityWidth = DisparityWidth::DISPARITY_96;

        /**
         * Disparity companding using sparse matching.
         * Matching pixel by pixel for N disparities.
         * Matching every 2nd pixel for M disparitites.
         * Matching every 4th pixel for T disparities.
         * In case of 96 disparities: N=48, M=32, T=16.
         * This way the search range is extended to 176 disparities, by sparse matching.
         * Note: when enabling this flag only depth map will be affected, disparity map is not.
         */
        bool enableCompanding = false;

        /**
         * Used only for debug purposes, SW postprocessing handled only invalid value of 0 properly.
         */
        uint8_t invalidDisparityValue = 0;

        /**
         * Disparities with confidence value under this threshold are accepted.
         * Higher confidence threshold means disparities with less confidence are accepted too.
         */
        uint8_t confidenceThreshold = 245;

        /**
         * The linear equation applied for computing the cost is:
         * COMB_COST = α*AD + β*(CTC<<3).
         * CLAMP(COMB_COST >> 5, threshold).
         * Where AD is the Absolute Difference between 2 pixels values.
         * CTC is the Census Transform Cost between 2 pixels, based on Hamming distance (xor).
         * The α and β parameters are subject to fine fine tuning by the user.
         */
        struct LinearEquationParameters {
            uint8_t alpha = 0;
            uint8_t beta = 2;
            uint8_t threshold = 127;

            NLOHMANN_DEFINE_TYPE_INTRUSIVE(LinearEquationParameters, alpha, beta, threshold);
        };

        /**
         * Cost calculation linear equation parameters.
         */
        LinearEquationParameters linearEquationParameters;

        NLOHMANN_DEFINE_TYPE_INTRUSIVE(CostMatching, disparityWidth, enableCompanding, invalidDisparityValue, confidenceThreshold, linearEquationParameters);
    };

    /**
     * Cost matching settings.
     */
    CostMatching costMatching;

    /**
     * Cost Aggregation is based on Semi Global Block Matching (SGBM). This algorithm uses a semi global
     * technique to aggregate the cost map. Ultimately the idea is to build inertia into the stereo algorithm. If
     * a pixel has very little texture information, then odds are the correct disparity for this pixel is close to
     * that of the previous pixel considered. This means that we get improved results in areas with low
     * texture.
     */
    struct CostAggregation {
        static constexpr const int defaultPenaltyP1 = 250;
        static constexpr const int defaultPenaltyP2 = 500;

        /**
         * Cost calculation linear equation parameters.
         */
        uint8_t divisionFactor = 1;

        /**
         * Horizontal P1 penalty cost parameter.
         */
        uint16_t horizontalPenaltyCostP1 = defaultPenaltyP1;
        /**
         * Horizontal P2 penalty cost parameter.
         */
        uint16_t horizontalPenaltyCostP2 = defaultPenaltyP2;

        /**
         * Vertical P1 penalty cost parameter.
         */
        uint16_t verticalPenaltyCostP1 = defaultPenaltyP1;
        /**
         * Vertical P2 penalty cost parameter.
         */
        uint16_t verticalPenaltyCostP2 = defaultPenaltyP2;

        NLOHMANN_DEFINE_TYPE_INTRUSIVE(
            CostAggregation, divisionFactor, horizontalPenaltyCostP1, horizontalPenaltyCostP2, verticalPenaltyCostP1, verticalPenaltyCostP2);
    };

    /**
     * Cost aggregation settings.
     */
    CostAggregation costAggregation;

    void serialize(std::vector<std::uint8_t>& metadata, DatatypeEnum& datatype) const override {
        nlohmann::json j = *this;
        metadata = nlohmann::json::to_msgpack(j);
        datatype = DatatypeEnum::StereoDepthConfig;
    };

    NLOHMANN_DEFINE_TYPE_INTRUSIVE(RawStereoDepthConfig, algorithmControl, postProcessing, censusTransform, costMatching, costAggregation);
};

}  // namespace dai
<commit_msg>Add temporal filter to config<commit_after>#pragma once
#include <cstdint>
#include <depthai-shared/common/optional.hpp>
#include <nlohmann/json.hpp>
#include <vector>

#include "DatatypeEnum.hpp"
#include "RawBuffer.hpp"

namespace dai {

/**
 * Median filter config for disparity post-processing
 */
enum class MedianFilter : int32_t { MEDIAN_OFF = 0, KERNEL_3x3 = 3, KERNEL_5x5 = 5, KERNEL_7x7 = 7 };

/// RawStereoDepthConfig configuration structure
struct RawStereoDepthConfig : public RawBuffer {
    using MedianFilter = dai::MedianFilter;

    struct AlgorithmControl {
        /**
         * Computes and combines disparities in both L-R and R-L directions, and combine them.
         * For better occlusion handling
         */
        bool enableLeftRightCheck = true;

        /**
         * Disparity range increased from 95 to 190, combined from full resolution and downscaled images.
         * Suitable for short range objects
         */
        bool enableExtended = false;

        /**
         * Computes disparity with sub-pixel interpolation (5 fractional bits), suitable for long range
         */
        bool enableSubpixel = false;

        /**
         * Left-right check threshold for left-right, right-left disparity map combine, 0..128
         * Used only when left-right check mode is enabled.
         * Defines the maximum difference between the confidence of pixels from left-right and right-left confidence maps
         */
        std::int32_t leftRightCheckThreshold = 10;

        /**
         * Number of fractional bits for subpixel mode.
         * Valid values: 3,4,5.
         * Defines the number of fractional disparities: 2^x.
         * Median filter postprocessing is supported only for 3 fractional bits.
         */
        std::int32_t subpixelFractionalBits = 3;

        NLOHMANN_DEFINE_TYPE_INTRUSIVE(AlgorithmControl, enableLeftRightCheck, enableExtended, enableSubpixel, leftRightCheckThreshold, subpixelFractionalBits);
    };

    /**
     * Controls the flow of stereo algorithm: left-right check, subpixel etc.
     */
    AlgorithmControl algorithmControl;

    struct PostProcessing {
        /**
         * Set kernel size for disparity/depth median filtering, or disable
         */
        MedianFilter median = MedianFilter::KERNEL_5x5;

        /**
         * Sigma value for bilateral filter. 0 means disabled
         * A larger value of the parameter means that farther colors within the pixel neighborhood will be mixed together.
         */
        std::int16_t bilateralSigmaValue = 0;

        struct TemporalFilter {
            bool enable = false;

            enum class PersistencyMode : int32_t {
                PERSISTENCY_OFF = 0,
                VALID_8_OUT_OF_8 = 1,
                VALID_2_IN_LAST_3 = 2,
                VALID_2_IN_LAST_4 = 3,
                VALID_2_OUT_OF_8 = 4,
                VALID_1_IN_LAST_2 = 5,
                VALID_1_IN_LAST_5 = 6,
                VALID_1_IN_LAST_8 = 7,
                PERSISTENCY_INDEFINITELY = 8,
            };

            PersistencyMode persistencyMode = PersistencyMode::VALID_2_IN_LAST_4;

            float alpha = 0.4f;
            std::int32_t delta = 20;
        };
        NLOHMANN_DEFINE_TYPE_INTRUSIVE(TemporalFilter, enable, persistencyMode, alpha, delta);

        TemporalFilter temporalFilter;

        NLOHMANN_DEFINE_TYPE_INTRUSIVE(PostProcessing, median, bilateralSigmaValue, temporalFilter);
    };

    /**
     * Controls the postprocessing of disparity and/or depth map.
     */
    PostProcessing postProcessing;

    /**
     * The basic cost function used by the Stereo Accelerator for matching the left and right images is the Census
     * Transform. It works on a block of pixels and computes a bit vector which represents the structure of the
     * image in that block.
     * There are two types of Census Transform based on how the middle pixel is used:
     * Classic Approach and Modified Census. The comparisons that are made between pixels can be or not thresholded.
     * In some cases a mask can be applied to filter out only specific bits from the entire bit stream.
     * All these approaches are:
     * Classic Approach: Uses middle pixel to compare against all its neighbors over a defined window. Each
     * comparison results in a new bit, that is 0 if central pixel is smaller, or 1 if is it bigger than its neighbor.
     * Modified Census Transform: same as classic Census Transform, but instead of comparing central pixel
     * with its neighbors, the window mean will be compared with each pixel over the window.
     * Thresholding Census Transform: same as classic Census Transform, but it is not enough that a
     * neighbor pixel to be bigger than the central pixel, it must be significant bigger (based on a threshold).
     * Census Transform with Mask: same as classic Census Transform, but in this case not all of the pixel from
     * the support window are part of the binary descriptor. We use a ma sk “M” to define which pixels are part
     * of the binary descriptor (1), and which pixels should be skipped (0).
     */
    struct CensusTransform {
        /**
         * Census transform kernel size possible values.
         */
        enum class KernelSize : std::int32_t { AUTO = -1, KERNEL_5x5 = 0, KERNEL_7x7, KERNEL_7x9 };

        /**
         * Census transform kernel size.
         */
        KernelSize kernelSize = KernelSize::AUTO;

        /**
         * Census transform mask, default: auto, mask is set based on resolution and kernel size.
         * Disabled for 400p input resolution.
         * Enabled for 720p.
         * 0XA82415 for 5x5 census transform kernel.
         * 0XAA02A8154055 for 7x7 census transform kernel.
         * 0X2AA00AA805540155 for 7x9 census transform kernel.
         * Empirical values.
         */
        uint64_t kernelMask = 0;

        /**
         * If enabled, each pixel in the window is compared with the mean window value instead of the central pixel.
         */
        bool enableMeanMode = true;

        /**
         * Census transform comparation treshold value.
         */
        uint32_t threshold = 0;

        NLOHMANN_DEFINE_TYPE_INTRUSIVE(CensusTransform, kernelSize, kernelMask, enableMeanMode, threshold);
    };

    /**
     * Census transform settings.
     */
    CensusTransform censusTransform;

    /**
     * The matching cost is way of measuring the similarity of image locations in stereo correspondence
     * algorithm. Based on the configuration parameters and based on the descriptor type, a linear equation
     * is applied to computing the cost for each candidate disparity at each pixel.
     */
    struct CostMatching {
        /**
         * Disparity search range: 64 or 96 pixels are supported by the HW.
         */
        enum class DisparityWidth : std::uint32_t { DISPARITY_64, DISPARITY_96 };

        /**
         * Disparity search range, default 96 pixels.
         */
        DisparityWidth disparityWidth = DisparityWidth::DISPARITY_96;

        /**
         * Disparity companding using sparse matching.
         * Matching pixel by pixel for N disparities.
         * Matching every 2nd pixel for M disparitites.
         * Matching every 4th pixel for T disparities.
         * In case of 96 disparities: N=48, M=32, T=16.
         * This way the search range is extended to 176 disparities, by sparse matching.
         * Note: when enabling this flag only depth map will be affected, disparity map is not.
         */
        bool enableCompanding = false;

        /**
         * Used only for debug purposes, SW postprocessing handled only invalid value of 0 properly.
         */
        uint8_t invalidDisparityValue = 0;

        /**
         * Disparities with confidence value under this threshold are accepted.
         * Higher confidence threshold means disparities with less confidence are accepted too.
         */
        uint8_t confidenceThreshold = 245;

        /**
         * The linear equation applied for computing the cost is:
         * COMB_COST = α*AD + β*(CTC<<3).
         * CLAMP(COMB_COST >> 5, threshold).
         * Where AD is the Absolute Difference between 2 pixels values.
         * CTC is the Census Transform Cost between 2 pixels, based on Hamming distance (xor).
         * The α and β parameters are subject to fine fine tuning by the user.
         */
        struct LinearEquationParameters {
            uint8_t alpha = 0;
            uint8_t beta = 2;
            uint8_t threshold = 127;

            NLOHMANN_DEFINE_TYPE_INTRUSIVE(LinearEquationParameters, alpha, beta, threshold);
        };

        /**
         * Cost calculation linear equation parameters.
         */
        LinearEquationParameters linearEquationParameters;

        NLOHMANN_DEFINE_TYPE_INTRUSIVE(CostMatching, disparityWidth, enableCompanding, invalidDisparityValue, confidenceThreshold, linearEquationParameters);
    };

    /**
     * Cost matching settings.
     */
    CostMatching costMatching;

    /**
     * Cost Aggregation is based on Semi Global Block Matching (SGBM). This algorithm uses a semi global
     * technique to aggregate the cost map. Ultimately the idea is to build inertia into the stereo algorithm. If
     * a pixel has very little texture information, then odds are the correct disparity for this pixel is close to
     * that of the previous pixel considered. This means that we get improved results in areas with low
     * texture.
     */
    struct CostAggregation {
        static constexpr const int defaultPenaltyP1 = 250;
        static constexpr const int defaultPenaltyP2 = 500;

        /**
         * Cost calculation linear equation parameters.
         */
        uint8_t divisionFactor = 1;

        /**
         * Horizontal P1 penalty cost parameter.
         */
        uint16_t horizontalPenaltyCostP1 = defaultPenaltyP1;
        /**
         * Horizontal P2 penalty cost parameter.
         */
        uint16_t horizontalPenaltyCostP2 = defaultPenaltyP2;

        /**
         * Vertical P1 penalty cost parameter.
         */
        uint16_t verticalPenaltyCostP1 = defaultPenaltyP1;
        /**
         * Vertical P2 penalty cost parameter.
         */
        uint16_t verticalPenaltyCostP2 = defaultPenaltyP2;

        NLOHMANN_DEFINE_TYPE_INTRUSIVE(
            CostAggregation, divisionFactor, horizontalPenaltyCostP1, horizontalPenaltyCostP2, verticalPenaltyCostP1, verticalPenaltyCostP2);
    };

    /**
     * Cost aggregation settings.
     */
    CostAggregation costAggregation;

    void serialize(std::vector<std::uint8_t>& metadata, DatatypeEnum& datatype) const override {
        nlohmann::json j = *this;
        metadata = nlohmann::json::to_msgpack(j);
        datatype = DatatypeEnum::StereoDepthConfig;
    };

    NLOHMANN_DEFINE_TYPE_INTRUSIVE(RawStereoDepthConfig, algorithmControl, postProcessing, censusTransform, costMatching, costAggregation);
};

}  // namespace dai
<|endoftext|>


<commit_before>// @(#)root/test:$Name:  $:$Id: hworld.cxx,v 1.5 2002/05/14 10:22:37 rdm Exp $
// Author: Fons Rademakers   04/04/97

// This small demo shows the traditional "Hello World". Its main use is
// to show how to use ROOT graphics and how to enter the eventloop to
// be able to interact with the graphics.

#include "TApplication.h"
#include "TCanvas.h"
#include "TLine.h"
#include "TPaveLabel.h"

int main(int argc, char **argv)
{
   TApplication theApp("App", &argc, argv);

   TCanvas *c = new TCanvas("c", "The Hello Canvas", 400, 400);
   //c->Connect("Closed()", "TApplication", &theApp, "Terminate()");

   TPaveLabel *hello = new TPaveLabel(0.2,0.4,0.8,0.6,"Hello World");
   hello->Draw();
   TPaveLabel *quit = new TPaveLabel(0.2,0.2,0.8,0.3,"Close via menu File/Quit");
   quit->Draw();
   c->Update();
   theApp.Run();
   return 0;
}
<commit_msg>Uncomment one statement<commit_after>// @(#)root/test:$Name:  $:$Id: hworld.cxx,v 1.6 2005/04/23 11:01:34 brun Exp $
// Author: Fons Rademakers   04/04/97

// This small demo shows the traditional "Hello World". Its main use is
// to show how to use ROOT graphics and how to enter the eventloop to
// be able to interact with the graphics.

#include "TApplication.h"
#include "TCanvas.h"
#include "TLine.h"
#include "TPaveLabel.h"

int main(int argc, char **argv)
{
   TApplication theApp("App", &argc, argv);

   TCanvas *c = new TCanvas("c", "The Hello Canvas", 400, 400);
   c->Connect("Closed()", "TApplication", &theApp, "Terminate()");

   TPaveLabel *hello = new TPaveLabel(0.2,0.4,0.8,0.6,"Hello World");
   hello->Draw();
   TPaveLabel *quit = new TPaveLabel(0.2,0.2,0.8,0.3,"Close via menu File/Quit");
   quit->Draw();
   c->Update();
   theApp.Run();
   return 0;
}
<|endoftext|>


<commit_before>#include <cassert>
#include <cstdlib>
#include <fstream>
#include <functional>
#include <iostream>
#include <random>
#include <sstream>
#include <vector>

#include "miopen/db_record.hpp"
#include "test.hpp"

namespace miopen {
namespace tests {

struct TestData
{
    int x;
    int y;

    TestData()
    {
        const int seed = 42;

        static std::mt19937 rng(seed);
        static std::uniform_int_distribution<std::mt19937::result_type> dist{};

        x = dist(rng);
        y = dist(rng);
    }

    TestData(int x_, int y_) : x(x_), y(y_) {}

    void Serialize(std::ostream& s) const
    {
        static const auto sep = ',';
        s << x << sep << y;
    }

    void LegacySerialize(std::ostream& s) const
    {
        Serialize(s);
        s << ",l";
    }

    bool Deserialize(const std::string& s)
    {
        static const auto sep = ',';
        TestData t;
        std::istringstream ss(s);

        auto success = DeserializeField(ss, &t.x, sep) && DeserializeField(ss, &t.y, sep);

        if(!success)
            return false;

        *this = t;
        return true;
    }

    bool LegacyDeserialize(const std::string& s) { return Deserialize(s); }
    bool operator==(const TestData& other) const { return x == other.x && y == other.y; }

    private:
    inline static bool DeserializeField(std::istream& from, int* ret, char separator)
    {
        std::string part;

        if(!std::getline(from, part, separator))
            return false;

        const auto start = part.c_str();
        char* end;
        auto value = std::strtol(start, &end, 10);

        if(start == end)
            return false;

        *ret = value;
        return true;
    }
};

std::ostream& operator<<(std::ostream& s, const TestData& td)
{
    s << "x: " << td.x << ", y: " << td.y;
    return s;
}

class DbRecordTest
{
    public:
    virtual ~DbRecordTest() { std::remove(TempFilePath()); }

    protected:
    static const TestData key;
    static const TestData value0;
    static const TestData value1;
    static const char* const id0;
    static const char* const id1;
    static const char* const missing_id;
    static const char* const legacy_id;

    static const char* TempFilePath() { return "/tmp/dbread.test.temp.pdb"; }
};

const TestData DbRecordTest::key(1, 2);
const TestData DbRecordTest::value0(3, 4);
const TestData DbRecordTest::value1(5, 6);
const char* const DbRecordTest::id0        = "0";
const char* const DbRecordTest::id1        = "1";
const char* const DbRecordTest::missing_id = "2";
const char* const DbRecordTest::legacy_id  = "ConvOclDirectFwd"; // const from db_record.cpp

class DbRecordReadTest : public DbRecordTest
{
    public:
    inline void Run()
    {
        std::ostringstream ss_vals;
        ss_vals << key.x << ',' << key.y << '=' << id1 << ':' << value1.x << ',' << value1.y << ';'
                << id0 << ':' << value0.x << ',' << value0.y;

        std::ofstream(TempFilePath()) << ss_vals.str() << std::endl;

        TestData read0, read1;

        {
            DbRecord record(TempFilePath(), key);

            EXPECT(record.Load(id0, read0));
            EXPECT(record.Load(id1, read1));
        }

        EXPECT_EQUAL(value0, read0);
        EXPECT_EQUAL(value1, read1);
    }
};

class DbRecordWriteTest : public DbRecordTest
{
    public:
    inline void Run()
    {
        std::ostringstream ss_vals;
        ss_vals << key.x << ',' << key.y << '=' << id1 << ':' << value1.x << ',' << value1.y << ';'
                << id0 << ':' << value0.x << ',' << value0.y;

        (void)std::ofstream(TempFilePath());

        {
            DbRecord record(TempFilePath(), key);

            EXPECT(record.Store(id0, value0));
            EXPECT(record.Store(id1, value1));
        }

        std::string read;

        EXPECT(std::getline(std::ifstream(TempFilePath()), read).good());
        EXPECT_EQUAL(read, ss_vals.str());
    }
};

#if MIOPEN_PERFDB_CONV_LEGACY_SUPPORT
class DbRecordLegacyReadTest : public DbRecordTest
{
    public:
    inline void Run()
    {
        std::ostringstream ss_vals;
        ss_vals << key.x << ',' << key.y << ",l " << value0.x << ',' << value0.y;

        std::ofstream(TempFilePath()) << ss_vals.str() << std::endl;

        TestData read;

        {
            DbRecord record(TempFilePath(), key, true);

            EXPECT(record.Load(legacy_id, read));
        }

        EXPECT_EQUAL(value0, read);
    }
};
#endif

class DbRecordOperationsTest : public DbRecordTest
{
    public:
    inline void Run()
    {
        (void)std::ofstream(TempFilePath()); // To suppress warning in logs.

        TestData to_be_rewritten(7, 8);

        {
            DbRecord record(TempFilePath(), key);

            EXPECT(record.Store(id0, to_be_rewritten));
            EXPECT(record.Store(id1, to_be_rewritten));

            // Rewritting existing value with other.
            EXPECT(record.Store(id1, value1));

            // Rewritting existing value with same. In fact no DB manipulation should be performed
            // inside of store in such case.
            EXPECT(record.Store(id1, value1));
        }

        {
            DbRecord record(TempFilePath(), key);

            // Rewriting existing value to store it to file.
            EXPECT(record.Store(id0, value0));
        }

        TestData read0, read1, read_missing, read_missing_cmp(read_missing);

        {
            DbRecord record(TempFilePath(), key);

            // Loading by id not present in record should execute well but return false as nothing
            // was read.
            EXPECT(!record.Load(missing_id, read_missing));

            // In such case value should not be changed.
            EXPECT_EQUAL(read_missing, read_missing_cmp);

            EXPECT(record.Load(id0, read0));
            EXPECT(record.Load(id1, read1));
        }

        EXPECT_EQUAL(read0, value0);
        EXPECT_EQUAL(read1, value1);
    }
};

} // namespace tests
} // namespace miopen

int main()
{
    miopen::tests::DbRecordReadTest().Run();
    miopen::tests::DbRecordWriteTest().Run();
#if MIOPEN_PERFDB_CONV_LEGACY_SUPPORT
    miopen::tests::DbRecordLegacyReadTest().Run();
#endif
    miopen::tests::DbRecordOperationsTest().Run();

    return 0;
}
<commit_msg>Added more ifdefs for legacy support.<commit_after>#include <cassert>
#include <cstdlib>
#include <fstream>
#include <functional>
#include <iostream>
#include <random>
#include <sstream>
#include <vector>

#include "miopen/db_record.hpp"
#include "test.hpp"

namespace miopen {
namespace tests {

struct TestData
{
    int x;
    int y;

    TestData()
    {
        const int seed = 42;

        static std::mt19937 rng(seed);
        static std::uniform_int_distribution<std::mt19937::result_type> dist{};

        x = dist(rng);
        y = dist(rng);
    }

    TestData(int x_, int y_) : x(x_), y(y_) {}

    void Serialize(std::ostream& s) const
    {
        static const auto sep = ',';
        s << x << sep << y;
    }

    bool Deserialize(const std::string& s)
    {
        static const auto sep = ',';
        TestData t;
        std::istringstream ss(s);

        auto success = DeserializeField(ss, &t.x, sep) && DeserializeField(ss, &t.y, sep);

        if(!success)
            return false;

        *this = t;
        return true;
    }

#if MIOPEN_PERFDB_CONV_LEGACY_SUPPORT
    void LegacySerialize(std::ostream& s) const
    {
        Serialize(s);
        s << ",l";
    }

    bool LegacyDeserialize(const std::string& s) { return Deserialize(s); }
#endif
    bool operator==(const TestData& other) const { return x == other.x && y == other.y; }

    private:
    inline static bool DeserializeField(std::istream& from, int* ret, char separator)
    {
        std::string part;

        if(!std::getline(from, part, separator))
            return false;

        const auto start = part.c_str();
        char* end;
        auto value = std::strtol(start, &end, 10);

        if(start == end)
            return false;

        *ret = value;
        return true;
    }
};

std::ostream& operator<<(std::ostream& s, const TestData& td)
{
    s << "x: " << td.x << ", y: " << td.y;
    return s;
}

class DbRecordTest
{
    public:
    virtual ~DbRecordTest() { std::remove(TempFilePath()); }

    protected:
    static const TestData key;
    static const TestData value0;
    static const TestData value1;
    static const char* const id0;
    static const char* const id1;
    static const char* const missing_id;
#if MIOPEN_PERFDB_CONV_LEGACY_SUPPORT
    static const char* const legacy_id;
#endif

    static const char* TempFilePath() { return "/tmp/dbread.test.temp.pdb"; }
};

const TestData DbRecordTest::key(1, 2);
const TestData DbRecordTest::value0(3, 4);
const TestData DbRecordTest::value1(5, 6);
const char* const DbRecordTest::id0        = "0";
const char* const DbRecordTest::id1        = "1";
const char* const DbRecordTest::missing_id = "2";
#if MIOPEN_PERFDB_CONV_LEGACY_SUPPORT
const char* const DbRecordTest::legacy_id  = "ConvOclDirectFwd"; // const from db_record.cpp
#endif

class DbRecordReadTest : public DbRecordTest
{
    public:
    inline void Run()
    {
        std::ostringstream ss_vals;
        ss_vals << key.x << ',' << key.y << '=' << id1 << ':' << value1.x << ',' << value1.y << ';'
                << id0 << ':' << value0.x << ',' << value0.y;

        std::ofstream(TempFilePath()) << ss_vals.str() << std::endl;

        TestData read0, read1;

        {
            DbRecord record(TempFilePath(), key);

            EXPECT(record.Load(id0, read0));
            EXPECT(record.Load(id1, read1));
        }

        EXPECT_EQUAL(value0, read0);
        EXPECT_EQUAL(value1, read1);
    }
};

class DbRecordWriteTest : public DbRecordTest
{
    public:
    inline void Run()
    {
        std::ostringstream ss_vals;
        ss_vals << key.x << ',' << key.y << '=' << id1 << ':' << value1.x << ',' << value1.y << ';'
                << id0 << ':' << value0.x << ',' << value0.y;

        (void)std::ofstream(TempFilePath());

        {
            DbRecord record(TempFilePath(), key);

            EXPECT(record.Store(id0, value0));
            EXPECT(record.Store(id1, value1));
        }

        std::string read;

        EXPECT(std::getline(std::ifstream(TempFilePath()), read).good());
        EXPECT_EQUAL(read, ss_vals.str());
    }
};

#if MIOPEN_PERFDB_CONV_LEGACY_SUPPORT
class DbRecordLegacyReadTest : public DbRecordTest
{
    public:
    inline void Run()
    {
        std::ostringstream ss_vals;
        ss_vals << key.x << ',' << key.y << ",l " << value0.x << ',' << value0.y;

        std::ofstream(TempFilePath()) << ss_vals.str() << std::endl;

        TestData read;

        {
            DbRecord record(TempFilePath(), key, true);

            EXPECT(record.Load(legacy_id, read));
        }

        EXPECT_EQUAL(value0, read);
    }
};
#endif

class DbRecordOperationsTest : public DbRecordTest
{
    public:
    inline void Run()
    {
        (void)std::ofstream(TempFilePath()); // To suppress warning in logs.

        TestData to_be_rewritten(7, 8);

        {
            DbRecord record(TempFilePath(), key);

            EXPECT(record.Store(id0, to_be_rewritten));
            EXPECT(record.Store(id1, to_be_rewritten));

            // Rewritting existing value with other.
            EXPECT(record.Store(id1, value1));

            // Rewritting existing value with same. In fact no DB manipulation should be performed
            // inside of store in such case.
            EXPECT(record.Store(id1, value1));
        }

        {
            DbRecord record(TempFilePath(), key);

            // Rewriting existing value to store it to file.
            EXPECT(record.Store(id0, value0));
        }

        TestData read0, read1, read_missing, read_missing_cmp(read_missing);

        {
            DbRecord record(TempFilePath(), key);

            // Loading by id not present in record should execute well but return false as nothing
            // was read.
            EXPECT(!record.Load(missing_id, read_missing));

            // In such case value should not be changed.
            EXPECT_EQUAL(read_missing, read_missing_cmp);

            EXPECT(record.Load(id0, read0));
            EXPECT(record.Load(id1, read1));
        }

        EXPECT_EQUAL(read0, value0);
        EXPECT_EQUAL(read1, value1);
    }
};

} // namespace tests
} // namespace miopen

int main()
{
    miopen::tests::DbRecordReadTest().Run();
    miopen::tests::DbRecordWriteTest().Run();
#if MIOPEN_PERFDB_CONV_LEGACY_SUPPORT
    miopen::tests::DbRecordLegacyReadTest().Run();
#endif
    miopen::tests::DbRecordOperationsTest().Run();

    return 0;
}
<|endoftext|>


<commit_before>/**
 * Copyright (c) 2011-2015 libbitcoin developers (see AUTHORS)
 *
 * This file is part of libbitcoin-server.
 *
 * libbitcoin-server is free software: you can redistribute it and/or
 * modify it under the terms of the GNU Affero General Public License with
 * additional permissions to the one published by the Free Software
 * Foundation, either version 3 of the License, or (at your option)
 * any later version. For more information see LICENSE.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
#include <boost/filesystem.hpp>
#include <boost/test/unit_test.hpp>
#include <bitcoin/server.hpp>

using namespace bc;
using namespace bc::blockchain;
using namespace bc::network;
using namespace bc::node;
using namespace bc::server;

struct low_thread_priority_fixture
{
    low_thread_priority_fixture()
    {
        set_thread_priority(thread_priority::lowest);
    }

    ~low_thread_priority_fixture()
    {
        set_thread_priority(thread_priority::normal);
    }
};

static void uninitchain(const char prefix[])
{
    boost::filesystem::remove_all(prefix);
}

static void initchain(const char prefix[])
{
    const size_t history_height = 0;
    const auto genesis = genesis_block();

    uninitchain(prefix);
    boost::filesystem::create_directories(prefix);
    initialize_blockchain(prefix);

    db_paths paths(prefix);
    db_interface interface(paths, { history_height });

    interface.start();
    interface.push(genesis);
}

BOOST_FIXTURE_TEST_SUITE(server_tests, low_thread_priority_fixture)

BOOST_AUTO_TEST_CASE(server_test)
{
    BOOST_REQUIRE(true);
}

BOOST_AUTO_TEST_SUITE_END()
<commit_msg>Kick travis with unimportant change.<commit_after>/**
 * Copyright (c) 2011-2015 libbitcoin developers (see AUTHORS)
 *
 * This file is part of libbitcoin-server.
 *
 * libbitcoin-server is free software: you can redistribute it and/or
 * modify it under the terms of the GNU Affero General Public License with
 * additional permissions to the one published by the Free Software
 * Foundation, either version 3 of the License, or (at your option)
 * any later version. For more information see LICENSE.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
#include <boost/filesystem.hpp>
#include <boost/test/unit_test.hpp>
#include <bitcoin/server.hpp>

using namespace bc;
using namespace bc::blockchain;
using namespace bc::network;
using namespace bc::node;
using namespace bc::server;

struct low_thread_priority_fixture
{
    low_thread_priority_fixture()
    {
        set_thread_priority(thread_priority::lowest);
    }

    ~low_thread_priority_fixture()
    {
        set_thread_priority(thread_priority::normal);
    }
};

static void uninitchain(const char prefix[])
{
    boost::filesystem::remove_all(prefix);
}

static void initchain(const char prefix[])
{
    const size_t history_height = 0;
    const auto genesis = genesis_block();

    uninitchain(prefix);
    boost::filesystem::create_directories(prefix);
    initialize_blockchain(prefix);

    db_paths paths(prefix);
    db_interface interface(paths, { history_height });

    interface.start();
    interface.push(genesis);
}

BOOST_FIXTURE_TEST_SUITE(server_tests, low_thread_priority_fixture)

BOOST_AUTO_TEST_CASE(server_test)
{
}

BOOST_AUTO_TEST_SUITE_END()
<|endoftext|>


<commit_before>
#include <PGTA/akPGTAc.h>
#include "akPGTADeviceImpl.h"
#include "akPGTAContextImpl.h"
#include "akPGTATrack.h"
#include <memory>
#include <string.h>

union PGTADeviceUnion
{
    HPGTADevice handle;
    PGTADeviceImpl* pgtaDevice;
};

union PGTAContextUnion
{
    HPGTAContext handle;
    PGTAContextImpl* pgtaContext;
};

union PGTATrackUnion
{
    HPGTATrack handle;
    PGTATrack* pgtaTrack;
};

union PGTATrackArrayUnion
{
    HPGTATrack* handle;
    PGTATrack** pgtaTracks;
};

HPGTADevice pgtaCreateDevice()
{
    PGTADeviceUnion temp;
    temp.pgtaDevice = new PGTADeviceImpl();
    if (!temp.pgtaDevice->Initialize())
    {
        delete temp.pgtaDevice;
        temp.pgtaDevice = nullptr;
    }
    return temp.handle;
}

void pgtaDestroyDevice(HPGTADevice device)
{
    if (!device)
    {
        return;
    }

    PGTADeviceUnion temp;
    temp.handle = device;
    temp.pgtaDevice->Shutdown();

    delete temp.pgtaDevice;
}

int pgtaCreateTracks(HPGTADevice device, const int numTracks, const char** trackSourcesIn,
                     const size_t* trackSourceLengths, HPGTATrack* tracksOut)
{
    if (!device)
    {
        return 0;
    }

    PGTATrackArrayUnion tracks;
    tracks.handle = tracksOut;

    PGTADeviceUnion temp;
    temp.handle = device;
    return temp.pgtaDevice->CreateTracks(numTracks, trackSourcesIn,
                                         trackSourceLengths, tracks.pgtaTracks);
}

void pgtaFreeTracks(HPGTADevice device, const int numTracks, HPGTATrack* tracksIn)
{
    if (!device)
    {
        return;
    }

    PGTATrackArrayUnion tracks;
    tracks.handle = tracksIn;

    PGTADeviceUnion temp;
    temp.handle = device;
    temp.pgtaDevice->FreeTracks(numTracks, tracks.pgtaTracks);
}

PGTATrackData pgtaGetTrackData(HPGTATrack track)
{
    if (!track)
    {
        return PGTATrackData();
    }

    PGTATrackUnion temp;
    temp.handle = track;

    return temp.pgtaTrack->GetTrackData(temp.handle);
}

void pgtaFreeTrackData(PGTATrackData trackData)
{
    PGTATrackUnion temp;
    temp.handle = trackData.trackHandle;

    if (!temp.pgtaTrack)
    {
        return;
    }

    temp.pgtaTrack->FreeTrackData();
}

void pgtaBindTrackSample(HPGTATrack track, const int32_t id, const uint8_t* audioData,
                         const size_t audioDataNumBytes)
{
    if (!track)
    {
        return;
    }

    PGTATrackUnion temp;
    temp.handle = track;

    int numSamples = (int)temp.pgtaTrack->GetNumSamples();
    auto* trackSamples = temp.pgtaTrack->GetSamplesForBinding();
    for (int i = 0; i < numSamples; ++i)
    {
        PGTATrackSample& trackSample = trackSamples->at(i);
        if (trackSample.id != id)
        {
            continue;
        }

        trackSample.audioData = audioData;
        trackSample.audioDataNumBytes = static_cast<uint32_t>(audioDataNumBytes);
        break;
    }
}

HPGTAContext pgtaCreateContext(HPGTADevice device, const PGTAConfig* config)
{
    if (!device || !config)
    {
        return nullptr;
    }

    PGTADeviceUnion devUnion;
    devUnion.handle = device;

    PGTAContextUnion contextUnion;
    contextUnion.pgtaContext = devUnion.pgtaDevice->CreateContext(*config);
    return contextUnion.handle;
}

void pgtaDestroyContext(HPGTADevice device, HPGTAContext context)
{
    if (!device || !context)
    {
        return;
    }

    PGTADeviceUnion devUnion;
    devUnion.handle = device;

    PGTAContextUnion contextUnion;
    contextUnion.handle = context;

    devUnion.pgtaDevice->DestroyContext(contextUnion.pgtaContext);
}

void pgtaBindTrack(HPGTAContext context, HPGTATrack track)
{
    if (!context || !track)
    {
        return;
    }

    PGTAContextUnion tempContext;
    tempContext.handle = context;

    PGTATrackUnion tempTrack;
    tempTrack.handle = track;

    tempContext.pgtaContext->BindTrack(tempTrack.pgtaTrack);
}

void pgtaTransition(HPGTAContext context, HPGTATrack track, const float percentAmount, const float durationSeconds)
{
    if (!context || !track)
    {
        return;
    }

    PGTAContextUnion tempContext;
    tempContext.handle = context;

    PGTATrackUnion tempTrack;
    tempTrack.handle = track;

    tempContext.pgtaContext->Transition(tempTrack.pgtaTrack, percentAmount, durationSeconds);
}

PGTABuffer pgtaUpdate(HPGTAContext context, float deltaSeconds)
{
    if (!context || deltaSeconds <= 0.0f)
    {
        return PGTABuffer();
    }

    PGTAContextUnion temp;
    temp.handle = context;
    return temp.pgtaContext->Update(deltaSeconds);
}

PGTABuffer pgtaGetOutputBuffer(HPGTAContext context)
{
    if (!context)
    {
        return PGTABuffer();
    }

    PGTAContextUnion temp;
    temp.handle = context;
    return temp.pgtaContext->GetOutputBuffer();
}

<commit_msg>Correct aliasing with unions for the c api<commit_after>
#include <PGTA/akPGTAc.h>
#include "akPGTADeviceImpl.h"
#include "akPGTAContextImpl.h"
#include "akPGTATrack.h"
#include <memory>
#include <string.h>

union PGTADeviceUnion
{
    HPGTADevice handle;
    PGTADeviceImpl* pgtaDevice;
};

union PGTAContextUnion
{
    HPGTAContext handle;
    PGTAContextImpl* pgtaContext;
};

union PGTATrackUnion
{
    HPGTATrack handle;
    PGTATrack* pgtaTrack;
};

union PGTATrackArrayUnion
{
    HPGTATrack* handle;
    PGTATrack** pgtaTracks;
};

HPGTADevice pgtaCreateDevice()
{
    PGTADeviceImpl* pgtaDevice = new PGTADeviceImpl();
    if (!pgtaDevice->Initialize())
    {
        delete pgtaDevice;
        pgtaDevice = nullptr;
    }
    return reinterpret_cast<PGTADeviceUnion*>(&pgtaDevice)->handle;
}

void pgtaDestroyDevice(HPGTADevice device)
{
    if (!device)
    {
        return;
    }

    PGTADeviceImpl* pgtaDevice = reinterpret_cast<PGTADeviceUnion*>(&device)->pgtaDevice;
    pgtaDevice->Shutdown();
    delete pgtaDevice;
}

int pgtaCreateTracks(HPGTADevice device, const int numTracks, const char** trackSourcesIn,
                     const size_t* trackSourceLengths, HPGTATrack* tracksOut)
{
    if (!device)
    {
        return 0;
    }

    PGTADeviceImpl* pgtaDevice = reinterpret_cast<PGTADeviceUnion*>(&device)->pgtaDevice;
    PGTATrack** pgtaTracks = reinterpret_cast<PGTATrackArrayUnion*>(&tracksOut)->pgtaTracks;

    return pgtaDevice->CreateTracks(numTracks, trackSourcesIn,
                                    trackSourceLengths, pgtaTracks);
}

void pgtaFreeTracks(HPGTADevice device, const int numTracks, HPGTATrack* tracksIn)
{
    if (!device)
    {
        return;
    }

    PGTADeviceImpl* pgtaDevice = reinterpret_cast<PGTADeviceUnion*>(&device)->pgtaDevice;
    PGTATrack** pgtaTracks = reinterpret_cast<PGTATrackArrayUnion*>(&tracksIn)->pgtaTracks;

    pgtaDevice->FreeTracks(numTracks, pgtaTracks);
}

PGTATrackData pgtaGetTrackData(HPGTATrack track)
{
    if (!track)
    {
        return PGTATrackData();
    }

    PGTATrack* pgtaTrack = reinterpret_cast<PGTATrackUnion*>(&track)->pgtaTrack;

    return pgtaTrack->GetTrackData(track);
}

void pgtaFreeTrackData(PGTATrackData trackData)
{
    PGTATrack* pgtaTrack = reinterpret_cast<PGTATrackUnion*>(&trackData.trackHandle)->pgtaTrack;
    if (!pgtaTrack)
    {
        return;
    }

    pgtaTrack->FreeTrackData();
}

void pgtaBindTrackSample(HPGTATrack track, const int32_t id, const uint8_t* audioData,
                         const size_t audioDataNumBytes)
{
    if (!track)
    {
        return;
    }

    PGTATrack* pgtaTrack = reinterpret_cast<PGTATrackUnion*>(&track)->pgtaTrack;
    for (PGTATrackSample& trackSample : *pgtaTrack->GetSamplesForBinding())
    {
        if (trackSample.id == id)
        {
            trackSample.audioData = audioData;
            trackSample.audioDataNumBytes = static_cast<uint32_t>(audioDataNumBytes);
            break;
        }
    }
}

HPGTAContext pgtaCreateContext(HPGTADevice device, const PGTAConfig* config)
{
    if (!device || !config)
    {
        return nullptr;
    }

    PGTADeviceImpl* pgtaDevice = reinterpret_cast<PGTADeviceUnion*>(&device)->pgtaDevice;
    PGTAContextImpl* pgtaContext = pgtaDevice->CreateContext(*config);

    return reinterpret_cast<PGTAContextUnion*>(&pgtaContext)->handle;
}

void pgtaDestroyContext(HPGTADevice device, HPGTAContext context)
{
    if (!device || !context)
    {
        return;
    }

    PGTADeviceImpl* pgtaDevice = reinterpret_cast<PGTADeviceUnion*>(&device)->pgtaDevice;
    PGTAContextImpl* pgtaContext = reinterpret_cast<PGTAContextUnion*>(&context)->pgtaContext;

    pgtaDevice->DestroyContext(pgtaContext);
}

void pgtaBindTrack(HPGTAContext context, HPGTATrack track)
{
    if (!context || !track)
    {
        return;
    }

    PGTAContextImpl* pgtaContext = reinterpret_cast<PGTAContextUnion*>(&context)->pgtaContext;
    PGTATrack* pgtaTrack = reinterpret_cast<PGTATrackUnion*>(&track)->pgtaTrack;

    pgtaContext->BindTrack(pgtaTrack);
}

void pgtaTransition(HPGTAContext context, HPGTATrack track, const float percentAmount, const float durationSeconds)
{
    if (!context || !track)
    {
        return;
    }

    PGTAContextImpl* pgtaContext = reinterpret_cast<PGTAContextUnion*>(&context)->pgtaContext;
    PGTATrack* pgtaTrack = reinterpret_cast<PGTATrackUnion*>(&track)->pgtaTrack;

    pgtaContext->Transition(pgtaTrack, percentAmount, durationSeconds);
}

PGTABuffer pgtaUpdate(HPGTAContext context, float deltaSeconds)
{
    if (!context || deltaSeconds <= 0.0f)
    {
        return PGTABuffer();
    }

    PGTAContextImpl* pgtaContext = reinterpret_cast<PGTAContextUnion*>(&context)->pgtaContext;

    return pgtaContext->Update(deltaSeconds);
}

PGTABuffer pgtaGetOutputBuffer(HPGTAContext context)
{
    if (!context)
    {
        return PGTABuffer();
    }

    PGTAContextImpl* pgtaContext = reinterpret_cast<PGTAContextUnion*>(&context)->pgtaContext;

    return pgtaContext->GetOutputBuffer();
}

<|endoftext|>


<commit_before>/*
 * Copyright (c) 2010, Tim Day <timday@timday.com>
 * Copyright (c) 2011, Michael P. Gerlek (mpg@flaxen.com)
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */
<commit_msg>comment<commit_after>/*
 * Copyright (c) 2010, Tim Day <timday@timday.com>
 * Copyright (c) 2011, Michael P. Gerlek (mpg@flaxen.com)
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

// All the functions are in the header, because if they are put in here then
// VS2010 freaks out about absurdly long mangled symbol names.
<|endoftext|>


<commit_before>// This is an independent project of an individual developer. Dear PVS-Studio, please check it.
// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
// MGenTest.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "MGenTest.h"
#include "../MGen/GLibrary/GLib.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

// The one and only application object

CWinApp theApp;

using namespace std;

CString current_dir;
ofstream logfile;
int continuous_integration = 0;
int nRetCode = 0;
vector<CString> errorMessages;
CString pname;

// Default time to start aborting generation
int wait_sec = 60;
// Default time to consider generation timeout
int wait_sec2 = 120;

void InitErrorMessages() {
	errorMessages.resize(1000);
	errorMessages[0] = "OK";
	errorMessages[10] = "MGen detected critical errors during run";
	errorMessages[11] = "MGen generator freeze on exit - possible error in generator";
	errorMessages[100] = "GetExitCodeProcess error in MGenTest (for MGen.exe)";
	errorMessages[101] = "MGen process did not exit correctly - possible crash";
	errorMessages[102] = "GetExitCodeProcess error in MGenTest";
}

CString GetErrorMessage(int e) {
	if (e < errorMessages.size()) return errorMessages[e];
	else return "";
}

void Run(CString fname, CString par, int delay) {
	DWORD ecode;
	SHELLEXECUTEINFO sei = { 0 };
	sei.cbSize = sizeof(SHELLEXECUTEINFO);
	sei.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI;
	sei.hwnd = NULL;
	sei.lpVerb = NULL;
	sei.lpFile = fname;
	sei.lpParameters = par;
	sei.lpDirectory = NULL;
	sei.nShow = SW_SHOWNORMAL;
	sei.hInstApp = NULL;
	ShellExecuteEx(&sei);
	WaitForSingleObject(sei.hProcess, delay);
	if (!GetExitCodeProcess(sei.hProcess, &ecode)) ecode = 102;
	if (ecode != 0 && ecode != 259) {
		nRetCode = 3;
		cout << "Exit code " << ecode << ": " << fname << " " << par << "\n";
	}
}

void Log(CString st, int level = 0) {
	cout << st;
	logfile << st;
	if (continuous_integration && level > 0) {
		CString cat;
		if (level == 1) cat = "Information";
		if (level == 2) cat = "Warning";
		if (level == 3) cat = "Error";
		CString par = "AddMessage \"" + st + "\" -Category " + cat + " >> autotest\\run.log 2>&1";
		Run("appveyor", par, 1000);
	}
}

CString file(CString fname) {
	CString st, st2;
	ifstream fs;
	// Check file exists
	if (!CGLib::fileExists(fname)) {
		cout << "Not found file " << fname << "\n";
	}
	fs.open(fname);
	char pch[2550];
	while (fs.good()) {
		// Get line
		fs.getline(pch, 2550);
		st2 = pch;
		if (!st2.IsEmpty()) {
			st += "- " + st2 + "\n";
		}
	}
	fs.close();
	return st;
}

void ClearBuffer() {
	fstream fs;
	fs.open("autotest\\buffer.log", ios::out);
	fs.close();
	remove("autotest\\exit.log");
}

void PublishTest(CString tname, int result, int tpassed, CString params) {
	CString emes = GetErrorMessage(result);
	CString st;
	CString st2;
	st2.Format("%s: code %d (%s) in %d ms\n", tname, result, emes, tpassed);
	if (result) {
		nRetCode = 2;
		Log(st2, 3);
	}
	else {
		Log(st2, 1);
	}

	// Show errors
	CString errors = file("autotest/buffer.log");
	cout << errors;

	if (continuous_integration) {
		CString cat = "Passed";
		if (result) cat = "Failed";
		st.Format("UpdateTest \"%s\" -Framework MSTest -FileName MGen.exe -Duration %d -Outcome %s -ErrorMessage \"%d: %s\" >> autotest\\run.log 2>&1", tname, tpassed, cat, result, emes);
		Run("appveyor", st, 1000);
		// Send errors separately in case of command line overflow
		st.Format("UpdateTest \"%s\" -Framework MSTest -FileName MGen.exe -Duration %d -Outcome %s -ErrorMessage \"%d: %s\" -StdOut \"MGen.exe %s\" -ErrorStackTrace \"%s\" >> autotest\\run.log 2>&1", tname, tpassed, cat, result, emes, params, errors);
		Run("appveyor", st, 1000);
	}
}

void LoadConfig() {
	long long time_start, time_stop;
	vector<CString> ast;
	CString fname = "autotest\\test.csv";
	// Check file exists
	if (!CGLib::fileExists(fname)) {
		cout << "Not found file " << fname << "\n";
	}
	// Clear expect.log
	remove("autotest\\expect.log");
	// Clear run.log
	fstream fs;
	fs.open("autotest\\run.log", ios::out);
	fs.close();
	// Open file
	fs.open(fname);
	DWORD ecode;
	CString st, st2;
	char pch[2550];
	int pos = 0;
	int passed;
	while (fs.good()) {
		fs.getline(pch, 2550);
		st = pch;
		pos = st.Find("#");
		if (pos != -1) st = st.Left(pos);
		st.Trim();
		if (st.GetLength()) {
			CGLib::Tokenize(st, ast, ";");
			pname = ast[0];
			if (ast.size() > 1 && atoi(ast[1]) > 0) wait_sec = atoi(ast[1]);
			if (ast.size() > 2 && atoi(ast[2]) > 0) wait_sec2 = atoi(ast[2]);
			ClearBuffer();
			if (continuous_integration) Run("appveyor", "AddTest \"" + pname + "\" -Framework MSTest -FileName MGen.exe -Outcome Running >> autotest\\run.log 2>&1", 1000);
			// MGen.exe -test=5 configs\GenCA2\good-cp5.pl
			st2.Format("-test=%d %s", wait_sec, pname);
			Log("Starting test config: " + st2 + "\n");
			SHELLEXECUTEINFO sei = { 0 };
			sei.cbSize = sizeof(SHELLEXECUTEINFO);
			sei.fMask = SEE_MASK_NOCLOSEPROCESS;
			sei.hwnd = NULL;
			sei.lpVerb = NULL;
			sei.lpFile = "MGen.exe";
			sei.lpParameters = st2;
			sei.lpDirectory = NULL;
			sei.nShow = SW_SHOW;
			sei.hInstApp = NULL;
			time_start = CGLib::time();
			ShellExecuteEx(&sei);
			if (WaitForSingleObject(sei.hProcess, wait_sec2 * 1000) == WAIT_TIMEOUT) {
				Log(pname + ": Timeout waiting for process\n", 3);
				exit(1);
			}

			time_stop = CGLib::time();
			passed = time_stop - time_start;
			if (!GetExitCodeProcess(sei.hProcess, &ecode)) ecode = 100;
			if (!CGLib::fileExists("autotest\\exit.log")) ecode = 101;

			PublishTest(pname, ecode, passed, st2);
		}
	}
	Run("appveyor", "PushArtifact autotest\\expect.log -Verbosity Normal -Type Auto -FileName expect.log >> run.log 2>&1", 1000);
	// Show run output
	//Run("cmd.exe", "/c echo Test >> autotest\\run.log", 1000);
	CString outs = file("autotest\\run.log");
	cout << "Run log:\n";
	cout << outs;
	// Show expect output
	outs = file("autotest\\expect.log");
	cout << "Expect log:\n";
	cout << outs;

	fs.close();
}

int test() {
	if (getenv("APPVEYOR_PROJECT_NAME") != NULL) {
		continuous_integration = 1;
	}
	logfile.open("autotest\\test.log", ios_base::app);

	TCHAR buffer[MAX_PATH];
	GetCurrentDirectory(MAX_PATH, buffer);
	current_dir = string(buffer).c_str();
	Log("Current dir: " + current_dir + "\n");

	LoadConfig();
	logfile.close();
	// Do not pause if continuous integration
	if (!continuous_integration) {
		cout << "Press any key to continue... ";
		_getch();
	}
	return 0;
}

int main()
{
	InitErrorMessages();
	HMODULE hModule = ::GetModuleHandle(nullptr);

    if (hModule != nullptr)
    {
        // initialize MFC and print and error on failure
        if (!AfxWinInit(hModule, nullptr, ::GetCommandLine(), 0))
        {
            wprintf(L"Fatal Error: MFC initialization failed\n");
            nRetCode = 4;
        }
        else
        {
					test();
				}
    }
    else
    {
        wprintf(L"Fatal Error: GetModuleHandle failed\n");
        nRetCode = 1;
    }

    return nRetCode;
}
<commit_msg>MGenTest: Publish sas-emu.log and cor-ack.log as artifacts to appveyor<commit_after>// This is an independent project of an individual developer. Dear PVS-Studio, please check it.
// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
// MGenTest.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "MGenTest.h"
#include "../MGen/GLibrary/GLib.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

// The one and only application object

CWinApp theApp;

using namespace std;

CString current_dir;
ofstream logfile;
int continuous_integration = 0;
int nRetCode = 0;
vector<CString> errorMessages;
CString pname;

// Default time to start aborting generation
int wait_sec = 60;
// Default time to consider generation timeout
int wait_sec2 = 120;

void InitErrorMessages() {
	errorMessages.resize(1000);
	errorMessages[0] = "OK";
	errorMessages[10] = "MGen detected critical errors during run";
	errorMessages[11] = "MGen generator freeze on exit - possible error in generator";
	errorMessages[100] = "GetExitCodeProcess error in MGenTest (for MGen.exe)";
	errorMessages[101] = "MGen process did not exit correctly - possible crash";
	errorMessages[102] = "GetExitCodeProcess error in MGenTest";
}

CString GetErrorMessage(int e) {
	if (e < errorMessages.size()) return errorMessages[e];
	else return "";
}

void Run(CString fname, CString par, int delay) {
	DWORD ecode;
	SHELLEXECUTEINFO sei = { 0 };
	sei.cbSize = sizeof(SHELLEXECUTEINFO);
	sei.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI;
	sei.hwnd = NULL;
	sei.lpVerb = NULL;
	sei.lpFile = fname;
	sei.lpParameters = par;
	sei.lpDirectory = NULL;
	sei.nShow = SW_SHOWNORMAL;
	sei.hInstApp = NULL;
	ShellExecuteEx(&sei);
	WaitForSingleObject(sei.hProcess, delay);
	if (!GetExitCodeProcess(sei.hProcess, &ecode)) ecode = 102;
	if (ecode != 0 && ecode != 259) {
		nRetCode = 3;
		cout << "Exit code " << ecode << ": " << fname << " " << par << "\n";
	}
}

void Log(CString st, int level = 0) {
	cout << st;
	logfile << st;
	if (continuous_integration && level > 0) {
		CString cat;
		if (level == 1) cat = "Information";
		if (level == 2) cat = "Warning";
		if (level == 3) cat = "Error";
		CString par = "AddMessage \"" + st + "\" -Category " + cat + " >> autotest\\run.log 2>&1";
		Run("appveyor", par, 1000);
	}
}

CString file(CString fname) {
	CString st, st2;
	ifstream fs;
	// Check file exists
	if (!CGLib::fileExists(fname)) {
		cout << "Not found file " << fname << "\n";
	}
	fs.open(fname);
	char pch[2550];
	while (fs.good()) {
		// Get line
		fs.getline(pch, 2550);
		st2 = pch;
		if (!st2.IsEmpty()) {
			st += "- " + st2 + "\n";
		}
	}
	fs.close();
	return st;
}

void ClearBuffer() {
	fstream fs;
	fs.open("autotest\\buffer.log", ios::out);
	fs.close();
	remove("autotest\\exit.log");
}

void PublishTest(CString tname, int result, int tpassed, CString params) {
	CString emes = GetErrorMessage(result);
	CString st;
	CString st2;
	st2.Format("%s: code %d (%s) in %d ms\n", tname, result, emes, tpassed);
	if (result) {
		nRetCode = 2;
		Log(st2, 3);
	}
	else {
		Log(st2, 1);
	}

	// Show errors
	CString errors = file("autotest/buffer.log");
	cout << errors;

	if (continuous_integration) {
		CString cat = "Passed";
		if (result) cat = "Failed";
		st.Format("UpdateTest \"%s\" -Framework MSTest -FileName MGen.exe -Duration %d -Outcome %s -ErrorMessage \"%d: %s\" >> autotest\\run.log 2>&1", tname, tpassed, cat, result, emes);
		Run("appveyor", st, 1000);
		// Send errors separately in case of command line overflow
		st.Format("UpdateTest \"%s\" -Framework MSTest -FileName MGen.exe -Duration %d -Outcome %s -ErrorMessage \"%d: %s\" -StdOut \"MGen.exe %s\" -ErrorStackTrace \"%s\" >> autotest\\run.log 2>&1", tname, tpassed, cat, result, emes, params, errors);
		Run("appveyor", st, 1000);
	}
}

void LoadConfig() {
	long long time_start, time_stop;
	vector<CString> ast;
	CString fname = "autotest\\test.csv";
	// Check file exists
	if (!CGLib::fileExists(fname)) {
		cout << "Not found file " << fname << "\n";
	}
	// Clear expect.log
	remove("autotest\\expect.log");
	remove("autotest\\sas-emu.log");
	remove("autotest\\cor-ack.log");
	// Clear run.log
	fstream fs;
	fs.open("autotest\\run.log", ios::out);
	fs.close();
	// Open file
	fs.open(fname);
	DWORD ecode;
	CString st, st2;
	char pch[2550];
	int pos = 0;
	int passed;
	while (fs.good()) {
		fs.getline(pch, 2550);
		st = pch;
		pos = st.Find("#");
		if (pos != -1) st = st.Left(pos);
		st.Trim();
		if (st.GetLength()) {
			CGLib::Tokenize(st, ast, ";");
			pname = ast[0];
			if (ast.size() > 1 && atoi(ast[1]) > 0) wait_sec = atoi(ast[1]);
			if (ast.size() > 2 && atoi(ast[2]) > 0) wait_sec2 = atoi(ast[2]);
			ClearBuffer();
			if (continuous_integration) Run("appveyor", "AddTest \"" + pname + "\" -Framework MSTest -FileName MGen.exe -Outcome Running >> autotest\\run.log 2>&1", 1000);
			// MGen.exe -test=5 configs\GenCA2\good-cp5.pl
			st2.Format("-test=%d %s", wait_sec, pname);
			Log("Starting test config: " + st2 + "\n");
			SHELLEXECUTEINFO sei = { 0 };
			sei.cbSize = sizeof(SHELLEXECUTEINFO);
			sei.fMask = SEE_MASK_NOCLOSEPROCESS;
			sei.hwnd = NULL;
			sei.lpVerb = NULL;
			sei.lpFile = "MGen.exe";
			sei.lpParameters = st2;
			sei.lpDirectory = NULL;
			sei.nShow = SW_SHOW;
			sei.hInstApp = NULL;
			time_start = CGLib::time();
			ShellExecuteEx(&sei);
			if (WaitForSingleObject(sei.hProcess, wait_sec2 * 1000) == WAIT_TIMEOUT) {
				Log(pname + ": Timeout waiting for process\n", 3);
				exit(1);
			}

			time_stop = CGLib::time();
			passed = time_stop - time_start;
			if (!GetExitCodeProcess(sei.hProcess, &ecode)) ecode = 100;
			if (!CGLib::fileExists("autotest\\exit.log")) ecode = 101;

			PublishTest(pname, ecode, passed, st2);
		}
	}
	Run("appveyor", "PushArtifact autotest\\expect.log -Verbosity Normal -Type Auto -FileName expect.log >> run.log 2>&1", 1000);
	Run("appveyor", "PushArtifact autotest\\sas-emu.log -Verbosity Normal -Type Auto -FileName sas-emu.log >> run.log 2>&1", 1000);
	Run("appveyor", "PushArtifact autotest\\cor-ack.log -Verbosity Normal -Type Auto -FileName cor-ack.log >> run.log 2>&1", 1000);
	// Show run output
	//Run("cmd.exe", "/c echo Test >> autotest\\run.log", 1000);
	CString outs = file("autotest\\run.log");
	cout << "Run log:\n";
	cout << outs;
	// Show expect output
	outs = file("autotest\\expect.log");
	cout << "Expect log:\n";
	cout << outs;
	outs = file("autotest\\sas-emu.log");
	cout << "SAS emulator log:\n";
	cout << outs;
	outs = file("autotest\\cor-ack.log");
	cout << "Correction acknowledge log:\n";
	cout << outs;

	fs.close();
}

int test() {
	if (getenv("APPVEYOR_PROJECT_NAME") != NULL) {
		continuous_integration = 1;
	}
	logfile.open("autotest\\test.log", ios_base::app);

	TCHAR buffer[MAX_PATH];
	GetCurrentDirectory(MAX_PATH, buffer);
	current_dir = string(buffer).c_str();
	Log("Current dir: " + current_dir + "\n");

	LoadConfig();
	logfile.close();
	// Do not pause if continuous integration
	if (!continuous_integration) {
		cout << "Press any key to continue... ";
		_getch();
	}
	return 0;
}

int main()
{
	InitErrorMessages();
	HMODULE hModule = ::GetModuleHandle(nullptr);

    if (hModule != nullptr)
    {
        // initialize MFC and print and error on failure
        if (!AfxWinInit(hModule, nullptr, ::GetCommandLine(), 0))
        {
            wprintf(L"Fatal Error: MFC initialization failed\n");
            nRetCode = 4;
        }
        else
        {
					test();
				}
    }
    else
    {
        wprintf(L"Fatal Error: GetModuleHandle failed\n");
        nRetCode = 1;
    }

    return nRetCode;
}
<|endoftext|>


<commit_before>#ifdef WITH_BASISU

#define BASISU_NO_ITERATOR_DEBUG_LEVEL

#ifdef __clang__
#pragma GCC diagnostic ignored "-Wunknown-warning-option"
#endif

#ifdef __GNUC__
#pragma GCC diagnostic ignored "-Wclass-memaccess"
#pragma GCC diagnostic ignored "-Wunused-value"
#endif

#include "encoder/basisu_comp.h"

static std::unique_ptr<basisu::job_pool> gJobPool;
static std::unique_ptr<basisu::job_pool> gEncPool;

void encodeBasisInit(int jobs)
{
	using namespace basisu;

	basisu_encoder_init();

	uint32_t num_threads = jobs == 0 ? std::thread::hardware_concurrency() : jobs;
	uint32_t num_threads_enc = num_threads * 2 / 3;

	// This is a little difficult to reason about. We want to distribute the pool capacity so that it adds up to num_threads.
	// We don't really know what the ratio of J:E work is (it's dependent on the mode among other things), but also encoding
	// work uses job threads as helpers if necessary, which is where "1+" is coming from.
	gJobPool.reset(new job_pool(num_threads - num_threads_enc));
	gEncPool.reset(new job_pool(1 + num_threads_enc));
}

bool encodeBasisInternal(const char* input, const char* output, bool yflip, bool normal_map, bool linear, bool uastc, int uastc_l, float uastc_q, int etc1s_l, int etc1s_q, int zstd_l, int width, int height)
{
	using namespace basisu;

	basist::etc1_global_selector_codebook sel_codebook(basist::g_global_selector_cb_size, basist::g_global_selector_cb);

	basis_compressor_params params;

	params.m_multithreading = gEncPool->get_total_threads() > 1;
	params.m_pJob_pool = gEncPool.get();

	if (uastc)
	{
		static const uint32_t s_level_flags[TOTAL_PACK_UASTC_LEVELS] = { cPackUASTCLevelFastest, cPackUASTCLevelFaster, cPackUASTCLevelDefault, cPackUASTCLevelSlower, cPackUASTCLevelVerySlow };

		params.m_uastc = true;

		params.m_pack_uastc_flags &= ~cPackUASTCLevelMask;
		params.m_pack_uastc_flags |= s_level_flags[uastc_l];

		params.m_rdo_uastc = uastc_q > 0;
		params.m_rdo_uastc_quality_scalar = uastc_q;
		params.m_rdo_uastc_dict_size = 1024;
	}
	else
	{
		params.m_compression_level = etc1s_l;
		params.m_quality_level = etc1s_q;
		params.m_max_endpoint_clusters = 0;
		params.m_max_selector_clusters = 0;

		params.m_no_selector_rdo = normal_map;
		params.m_no_endpoint_rdo = normal_map;
	}

	params.m_perceptual = !linear;

	params.m_mip_gen = true;
	params.m_mip_srgb = !linear;

	params.m_resample_width = width;
	params.m_resample_height = height;

	params.m_y_flip = yflip;

	params.m_create_ktx2_file = true;
	params.m_ktx2_srgb_transfer_func = !linear;

	if (zstd_l)
	{
		params.m_ktx2_uastc_supercompression = basist::KTX2_SS_ZSTANDARD;
		params.m_ktx2_zstd_supercompression_level = zstd_l;
	}

	params.m_read_source_images = true;
	params.m_write_output_basis_files = true;
	params.m_pSel_codebook = &sel_codebook;

	params.m_source_filenames.resize(1);
	params.m_source_filenames[0] = input;

	params.m_out_filename = output;

	params.m_status_output = false;

	basis_compressor c;

	if (!c.init(params))
		return false;

	return c.process() == basis_compressor::cECSuccess;
}

void encodePush(const std::function<void()>& job)
{
	assert(gJobPool);

	gJobPool->add_job(job);
}

void encodeWait()
{
	assert(gJobPool);

	gJobPool->wait_for_all();
}
#endif
<commit_msg>gltfpack: Switch to token-based pool from basis_universal fork<commit_after>#ifdef WITH_BASISU

#define BASISU_NO_ITERATOR_DEBUG_LEVEL

#ifdef __clang__
#pragma GCC diagnostic ignored "-Wunknown-warning-option"
#endif

#ifdef __GNUC__
#pragma GCC diagnostic ignored "-Wclass-memaccess"
#pragma GCC diagnostic ignored "-Wunused-value"
#endif

#include "encoder/basisu_comp.h"

static std::unique_ptr<basisu::job_pool> gJobPool;

void encodeBasisInit(int jobs)
{
	using namespace basisu;

	basisu_encoder_init();

	uint32_t num_threads = jobs == 0 ? std::thread::hardware_concurrency() : jobs;

	gJobPool.reset(new job_pool(num_threads));
}

bool encodeBasisInternal(const char* input, const char* output, bool yflip, bool normal_map, bool linear, bool uastc, int uastc_l, float uastc_q, int etc1s_l, int etc1s_q, int zstd_l, int width, int height)
{
	using namespace basisu;

	basist::etc1_global_selector_codebook sel_codebook(basist::g_global_selector_cb_size, basist::g_global_selector_cb);

	basis_compressor_params params;

	params.m_multithreading = gJobPool->get_total_threads() > 1;
	params.m_pJob_pool = gJobPool.get();

	if (uastc)
	{
		static const uint32_t s_level_flags[TOTAL_PACK_UASTC_LEVELS] = { cPackUASTCLevelFastest, cPackUASTCLevelFaster, cPackUASTCLevelDefault, cPackUASTCLevelSlower, cPackUASTCLevelVerySlow };

		params.m_uastc = true;

		params.m_pack_uastc_flags &= ~cPackUASTCLevelMask;
		params.m_pack_uastc_flags |= s_level_flags[uastc_l];

		params.m_rdo_uastc = uastc_q > 0;
		params.m_rdo_uastc_quality_scalar = uastc_q;
		params.m_rdo_uastc_dict_size = 1024;
	}
	else
	{
		params.m_compression_level = etc1s_l;
		params.m_quality_level = etc1s_q;
		params.m_max_endpoint_clusters = 0;
		params.m_max_selector_clusters = 0;

		params.m_no_selector_rdo = normal_map;
		params.m_no_endpoint_rdo = normal_map;
	}

	params.m_perceptual = !linear;

	params.m_mip_gen = true;
	params.m_mip_srgb = !linear;

	params.m_resample_width = width;
	params.m_resample_height = height;

	params.m_y_flip = yflip;

	params.m_create_ktx2_file = true;
	params.m_ktx2_srgb_transfer_func = !linear;

	if (zstd_l)
	{
		params.m_ktx2_uastc_supercompression = basist::KTX2_SS_ZSTANDARD;
		params.m_ktx2_zstd_supercompression_level = zstd_l;
	}

	params.m_read_source_images = true;
	params.m_write_output_basis_files = true;
	params.m_pSel_codebook = &sel_codebook;

	params.m_source_filenames.resize(1);
	params.m_source_filenames[0] = input;

	params.m_out_filename = output;

	params.m_status_output = false;

	basis_compressor c;

	if (!c.init(params))
		return false;

	return c.process() == basis_compressor::cECSuccess;
}

void encodePush(const std::function<void()>& job)
{
	assert(gJobPool);

	gJobPool->add_job(job, nullptr); // explicitly pass token to make sure we're using thread-safe job_pool implementation
}

void encodeWait()
{
	assert(gJobPool);

	gJobPool->wait_for_all();
}
#endif
<|endoftext|>


<commit_before>/*
 * Copyright 2016 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "gm.h"
#include "SkBlurMask.h"
#include "SkBlurMaskFilter.h"
#include "SkPath.h"

class SimpleRectGM : public skiagm::GM {
public:
    SimpleRectGM() {}

protected:
    SkString onShortName() override {
        SkString name;
        name.printf("simplerect");
        return name;
    }

    SkISize onISize() override {
        return SkISize::Make(800, 600);
    }

    void onDraw(SkCanvas* canvas) override {
        const SkScalar min = -20;
        const SkScalar max = 800;
        const SkScalar size = 20;

        SkRandom rand;
        SkPaint paint;
        for (int i = 0; i < 10000; i++) {
            paint.setColor(sk_tool_utils::color_to_565(rand.nextU() | (0xFF << 24)));
            canvas->drawRect(SkRect::MakeXYWH(rand.nextRangeScalar(min, max),
                                              rand.nextRangeScalar(min, max),
                                              rand.nextRangeScalar(0, size),
                                              rand.nextRangeScalar(0, size)),
                             paint);
        }
    }

    bool onAnimate(const SkAnimTimer& timer) override {
        return true;
    }

private:

    typedef GM INHERITED;
};
DEF_GM(return new SimpleRectGM;)
<commit_msg>must call rand in reliable order for bots<commit_after>/*
 * Copyright 2016 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "gm.h"
#include "SkBlurMask.h"
#include "SkBlurMaskFilter.h"
#include "SkPath.h"

class SimpleRectGM : public skiagm::GM {
public:
    SimpleRectGM() {}

protected:
    SkString onShortName() override {
        SkString name;
        name.printf("simplerect");
        return name;
    }

    SkISize onISize() override {
        return SkISize::Make(800, 800);
    }

    void onDraw(SkCanvas* canvas) override {
        const SkScalar min = -20;
        const SkScalar max = 800;
        const SkScalar size = 20;

        SkRandom rand;
        SkPaint paint;
        for (int i = 0; i < 10000; i++) {
            paint.setColor(sk_tool_utils::color_to_565(rand.nextU() | (0xFF << 24)));
            SkScalar x = rand.nextRangeScalar(min, max);
            SkScalar y = rand.nextRangeScalar(min, max);
            SkScalar w = rand.nextRangeScalar(0, size);
            SkScalar h = rand.nextRangeScalar(0, size);
            canvas->drawRect(SkRect::MakeXYWH(x, y, w, h), paint);
        }
    }

    bool onAnimate(const SkAnimTimer& timer) override {
        return true;
    }

private:

    typedef GM INHERITED;
};
DEF_GM(return new SimpleRectGM;)
<|endoftext|>


<commit_before>#include <iostream>
#include <iomanip> // << fixed << setprecision(xxx)
#include <algorithm> // do { } while ( next_permutation(A, A+xxx) ) ;
#include <vector>
#include <string> // to_string(nnn) // substr(m, n) // stoi(nnn)
#include <complex>
#include <tuple> // get<n>(xxx)
#include <queue>
#include <stack>
#include <map> // if (M.find(key) != M.end()) { }
#include <set> // S.insert(M);
// if (S.find(key) != S.end()) { }
// for (auto it=S.begin(); it != S.end(); it++) { }
// auto it = S.lower_bound(M);
#include <random> // random_device rd; mt19937 mt(rd());
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib> // atoi(xxx)
using namespace std;

#define DEBUG 0 // change 0 -> 1 if we need debug.
// insert #if<tab> by my emacs. #if DEBUG == 1 ... #end

typedef long long ll;

// const int dx[4] = {1, 0, -1, 0};
// const int dy[4] = {0, 1, 0, -1};

// const int C = 1e6+10;
// const ll M = 1000000007;

int N;
ll a[100010];

int main () {
  cin >> N;
  N = 3 * N;
  for (auto i = 0; i < N; ++i) {
    cin >> a[i];
  }
  sort(a, a+N);
  reverse(a, a+N);
  ll ans = 0;
  int M = N/3;
  int cnt = 0;
  for (auto i = 0; i < N; ++i) {
    if (i%2 == 1) {
      ans += a[i];
      ++cnt;
      if (M == cnt) break;
    }
  }
  cout << ans << endl;
}
<commit_msg>submit A.cpp to 'A - AtCoder Group Contest' (agc012) [C++14 (GCC 5.4.1)]<commit_after>#include <iostream>
#include <iomanip> // << fixed << setprecision(xxx)
#include <algorithm> // do { } while ( next_permutation(A, A+xxx) ) ;
#include <vector>
#include <string> // to_string(nnn) // substr(m, n) // stoi(nnn)
#include <complex>
#include <tuple> // get<n>(xxx)
#include <queue>
#include <stack>
#include <map> // if (M.find(key) != M.end()) { }
#include <set> // S.insert(M);
// if (S.find(key) != S.end()) { }
// for (auto it=S.begin(); it != S.end(); it++) { }
// auto it = S.lower_bound(M);
#include <random> // random_device rd; mt19937 mt(rd());
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib> // atoi(xxx)
using namespace std;

#define DEBUG 0 // change 0 -> 1 if we need debug.
// insert #if<tab> by my emacs. #if DEBUG == 1 ... #end

typedef long long ll;

// const int dx[4] = {1, 0, -1, 0};
// const int dy[4] = {0, 1, 0, -1};

// const int C = 1e6+10;
// const ll M = 1000000007;

int N;
ll a[300010];

int main () {
  cin >> N;
  N = 3 * N;
  for (auto i = 0; i < N; ++i) {
    cin >> a[i];
  }
  sort(a, a+N);
  reverse(a, a+N);
  ll ans = 0;
  int M = N/3;
  int cnt = 0;
  for (auto i = 0; i < N; ++i) {
    if (i%2 == 1) {
      ans += a[i];
      ++cnt;
      if (M == cnt) break;
    }
  }
  cout << ans << endl;
}
<|endoftext|>