Blizzard / s2client-api

StarCraft II Client - C++ library supported on Windows, Linux and Mac designed for building scripted bots and research using the SC2API.
MIT License
1.66k stars 282 forks source link

support 1-bit-per-pixel ImageData #311

Open mboedigh opened 5 years ago

mboedigh commented 5 years ago

SC2 now has 1-bit-per pixel imagedata for pathable_grid and placement_grid. SampleImageData needs to detect this and parse the image correctly. I don't know how to do a pull-request, but I think something like this works: Just replace two of the SampleImageData functions with the ones below.

    inline int8_t getBit(std::string const& str, int j)
    {
        div_t d = div(j, 8);
        unsigned char data = str[d.quot] >> (7 - d.rem);
        return  data & 1;
    }
    static bool SampleImageBit(const std::string& data, int width, int height, const Point2D& point, unsigned char& result) {
        Point2DI pointI(int(point.x), int(point.y));
        if (pointI.x < 0 || pointI.x >= width || pointI.y < 0 || pointI.y >= height) {
            return false;
        }

        //const int idx = pointI.x + (height - 1 - pointI.y) * width;
        const int idx = pointI.x + pointI.y * width;
        result = getBit(data, idx);
        return true;
    }

    static bool SampleImageData(const SC2APIProtocol::ImageData& data, const Point2D& point, unsigned char& result) {
        if (data.bits_per_pixel() == 1)
            return SampleImageBit(data.data(), data.size().x(), data.size().y(), point, result);
        else if (data.bits_per_pixel() == 8)
            return SampleImageData(data.data(), data.size().x(), data.size().y(), point, result);
        else
            return false;
    }

    static bool SampleImageData(const ImageData& data, const Point2D& point, unsigned char& result) {
        if (data.bits_per_pixel == 1)
            return SampleImageBit(data.data, data.width, data.height, point, result);
        else if (data.bits_per_pixel == 8)
            return SampleImageData(data.data, data.width, data.height, point, result);
        else
            return false;
    }