示例#1
0
void project_files(
    const std::string& name,
    const std::string& method,
    const std::string& from, index_t fromStride, index_t fromRows, index_t fromCols,
    int lng1, int lng2, int lat1, int lat2,
    const std::string& to, index_t toStride, index_t toRows, index_t toCols,
    index_t x, index_t y, index_t totalWidth, index_t totalHeight
) {
  boost::shared_ptr<Projection<T> > pProject = getProjection<T>(name);
  if (!pProject) {
    Rcpp::stop("Unsupported projection: %s", name);
  }
  boost::shared_ptr<Interpolator<T> > pInterp = getInterpolator<T>(method);
  if (!pInterp) {
    Rcpp::stop("Unsupported interpolator: %s", method);
  }

  // Memory mapped files
  MMFile<T> from_f(from, boost::interprocess::read_only);
  MMFile<T> to_f(to, boost::interprocess::read_write);

  // Grid will help us conveniently offset into mmap by row/col
  Grid<T> from_g(from_f.begin(), from_f.end(), fromStride, fromRows, fromCols);
  Grid<T> to_g(to_f.begin(), to_f.end(), toStride, toRows, toCols);

  project<T>(pProject.get(), pInterp.get(), from_g, lat1, lat2, lng1, lng2,
    to_g, x, totalWidth, y, totalHeight);
}
示例#2
0
float modify_alpha(read_info *input_image, int ie_bug)
{
    /* IE6 makes colors with even slightest transparency completely transparent,
       thus to improve situation in IE, make colors that are less than ~10% transparent
       completely opaque */

    rgb_pixel **input_pixels = (rgb_pixel **)input_image->row_pointers;
    rgb_pixel *pP;
    int rows= input_image->height, cols = input_image->width;
    double gamma = input_image->gamma;
    float min_opaque_val, almost_opaque_val;

    if (ie_bug) {
        min_opaque_val = 238.0/256.0; /* rest of the code uses min_opaque_val rather than checking for ie_bug */
        almost_opaque_val = min_opaque_val * 169.0/256.0;

        verbose_printf("  Working around IE6 bug by making image less transparent...\n");
    } else {
        min_opaque_val = almost_opaque_val = 1;
    }

    for(int row = 0; row < rows; ++row) {
        pP = input_pixels[row];
        for(int col = 0; col < cols; ++col, ++pP) {
            f_pixel px = to_f(gamma, *pP);

#ifndef NDEBUG
            rgb_pixel rgbcheck = to_rgb(gamma, px);


            if (pP->a && (pP->r != rgbcheck.r || pP->g != rgbcheck.g || pP->b != rgbcheck.b || pP->a != rgbcheck.a)) {
                fprintf(stderr, "Conversion error: expected %d,%d,%d,%d got %d,%d,%d,%d\n",
                        pP->r,pP->g,pP->b,pP->a, rgbcheck.r,rgbcheck.g,rgbcheck.b,rgbcheck.a);
                return -1;
            }
#endif
            /* set all completely transparent colors to black */
            if (!pP->a) {
                *pP = (rgb_pixel){0,0,0,pP->a};
            }
            /* ie bug: to avoid visible step caused by forced opaqueness, linearily raise opaqueness of almost-opaque colors */
            else if (pP->a < 255 && px.a > almost_opaque_val) {
                assert((min_opaque_val-almost_opaque_val)>0);

                float al = almost_opaque_val + (px.a-almost_opaque_val) * (1-almost_opaque_val) / (min_opaque_val-almost_opaque_val);
                if (al > 1) al = 1;
                px.a = al;
                pP->a = to_rgb(gamma, px).a;
            }
        }
    }

    return min_opaque_val;
}
示例#3
0
void set_palette(write_info *output_image, colormap *map)
{
    for (int x = 0; x < map->colors; ++x) {
        rgb_pixel px = to_rgb(output_image->gamma, map->palette[x].acolor);
        map->palette[x].acolor = to_f(output_image->gamma, px); /* saves rounding error introduced by to_rgb, which makes remapping & dithering more accurate */

        output_image->palette[x].red   = px.r;
        output_image->palette[x].green = px.g;
        output_image->palette[x].blue  = px.b;
        output_image->trans[x]         = px.a;
    }
}
示例#4
0
float remap_to_palette(read_info *input_image, write_info *output_image, colormap *map, float min_opaque_val, int ie_bug)
{
    rgb_pixel **input_pixels = (rgb_pixel **)input_image->row_pointers;
    unsigned char **row_pointers = output_image->row_pointers;
    int rows = input_image->height, cols = input_image->width;
    double gamma = input_image->gamma;

    int remapped_pixels=0;
    float remapping_error=0;

    int transparent_ind = best_color_index((f_pixel){0,0,0,0}, map, min_opaque_val, NULL);

    f_pixel average_color[map->colors];
    float average_color_count[map->colors];
    viter_init(map, average_color, average_color_count, NULL, NULL);

    for (int row = 0; row < rows; ++row) {
        for(int col = 0; col < cols; ++col) {

            f_pixel px = to_f(gamma, input_pixels[row][col]);
            int match;

            if (px.a < 1.0/256.0) {
                match = transparent_ind;
            } else {
                float diff;
                match = best_color_index(px, map,min_opaque_val, &diff);

                remapped_pixels++;
                remapping_error += diff;
            }

            row_pointers[row][col] = match;

            viter_update_color(px, 1.0, map, match, average_color, average_color_count, NULL, NULL);
        }
    }

    viter_finalize(map, average_color, average_color_count);

    return remapping_error / MAX(1,remapped_pixels);
}
示例#5
0
 Vector2 Vector2i::GetNormalized(void) const
 {
   Vector2 floats = to_f();
   floats.Normalize();
   return floats;
 }
示例#6
0
Vector3 Vector3i::GetNormalized()
{
    Vector3 floats = to_f();
    floats.Normalize();
    return floats;
}
示例#7
0
    int Number::compare(const Number& num) const
    {
#ifndef PMP_DISABLE_VECTOR
        if (is_v() || num.is_v())
        {
            bool comparisons[3];
            compare(num, comparisons);
            if (comparisons[0])      return -1;
            else if (comparisons[1]) return 0;
            else if (comparisons[2]) return 1;
            else return -2;
        }
#endif

        floating_type f;
        switch (type())
        {
        case Number::INTEGER:
            switch (num.type())
            {
            case Number::INTEGER:
                return get_i().compare(num.get_i());

            case Number::FLOATING:
                f = to_f();
                return f.compare(num.get_f());

            case Number::RATIONAL:
                f = to_f();
                return f.compare(num.to_f());

            default:
                assert(0);
                return 0;
            }

        case Number::FLOATING:
            switch (num.type())
            {
            case Number::INTEGER:
                f = num.to_f();
                return get_f().compare(f);

            case Number::FLOATING:
                return get_f().compare(num.get_f());

            case Number::RATIONAL:
                return get_f().compare(num.to_f());

            default:
                assert(0);
                return 0;
            }

        case Number::RATIONAL:
            switch (num.type())
            {
            case Number::INTEGER:
                f = num.to_f();
                return to_f().compare(f);

            case Number::FLOATING:
                return to_f().compare(num.get_f());

            case Number::RATIONAL:
                return to_f().compare(num.to_f());

            default:
                assert(0);
                return 0;
            }

        default:
            assert(0);
            return 0;
        }
    }
示例#8
0
    Number& Number::operator+=(const Number& num)
    {
#ifndef PMP_DISABLE_VECTOR
        if (is_v() || num.is_v())
        {
            vector_type vec;
            for (size_t i = 0; i < size(); ++i)
            {
                for (size_t j = 0; j < num.size(); ++j)
                {
                    Number tmp((*this)[i]);
                    tmp += num[j];
                    vec.push_back(tmp);
                }
            }
            assign(vec);
            return *this;
        }
#endif  // ndef PMP_DISABLE_VECTOR
        integer_type    i;
        floating_type   f;
        rational_type   r;
        switch (type())
        {
        case Number::INTEGER:
            switch (num.type())
            {
            case Number::INTEGER:
                i = get_i();
                i += num.get_i();
                assign(i);
                break;

            case Number::FLOATING:
                f = to_f();
                f += num.get_f();
                assign(f);
                break;

            case Number::RATIONAL:
                r = to_r();
                r += num.get_r();
                assign(r);
                break;

            default:
                assert(0);
                break;
            }
            break;

        case Number::FLOATING:
            switch (num.type())
            {
            case Number::INTEGER:
                f = get_f();
                f += num.to_f();
                assign(f);
                break;

            case Number::FLOATING:
                f = get_f();
                f += num.get_f();
                assign(f);
                break;

            case Number::RATIONAL:
                f = get_f();
                f += num.to_f();
                assign(f);
                break;

            default:
                assert(0);
                break;
            }
            break;

        case Number::RATIONAL:
            switch (num.type())
            {
            case Number::INTEGER:
                r = get_r();
                r += num.to_r();
                assign(r);
                break;

            case Number::FLOATING:
                f = to_f();
                f += num.get_f();
                assign(f);
                break;

            case Number::RATIONAL:
                r = get_r();
                r += num.get_r();
                assign(r);
                break;

            default:
                assert(0);
                break;
            }
            break;

        default:
            assert(0);
            break;
        }
        return *this;
    }
示例#9
0
    Number& Number::operator%=(const Number& num)
    {
#ifndef PMP_DISABLE_VECTOR
        if (is_v() || num.is_v())
        {
            vector_type vec;
            for (size_t i = 0; i < size(); ++i)
            {
                for (size_t j = 0; j < num.size(); ++j)
                {
                    Number tmp((*this)[i]);
                    tmp %= num[j];
                    vec.push_back(tmp);
                }
            }
            assign(vec);
            return *this;
        }
#endif
        integer_type    i;
        floating_type   f;
        rational_type   r;
        switch (type())
        {
        case Number::INTEGER:
            switch (num.type())
            {
            case Number::INTEGER:
                i = get_i();
                i %= num.get_i();
                assign(i);
                break;

            case Number::FLOATING:
                f = to_f();
                f = b_mp::fmod(f, num.get_f());
                assign(f);
                break;

            default:
                assert(0);
                break;
            }
            break;

        case Number::FLOATING:
            switch (num.type())
            {
            case Number::INTEGER:
                f = get_f();
                f = b_mp::fmod(f, static_cast<floating_type>(num.get_i()));
                assign(f);
                break;

            case Number::FLOATING:
                f = get_f();
                f = b_mp::fmod(f, num.get_f());
                assign(f);
                break;

            default:
                assert(0);
                break;
            }
            break;

        default:
            assert(0);
            break;
        }
        return *this;
    }
示例#10
0
    Number& Number::operator/=(const Number& num)
    {
#ifndef PMP_DISABLE_VECTOR
        if (is_v() || num.is_v())
        {
            vector_type vec;
            for (size_t i = 0; i < size(); ++i)
            {
                for (size_t j = 0; j < num.size(); ++j)
                {
                    Number tmp((*this)[i]);
                    tmp /= num[j];
                    vec.push_back(tmp);
                }
            }
            assign(vec);
            return *this;
        }
#endif
        integer_type    i;
        floating_type   f;
        rational_type   r;
        switch (type())
        {
        case Number::INTEGER:
            switch (num.type())
            {
            case Number::INTEGER:
                if (s_intdiv_type == Number::INTEGER)
                {
                    i = get_i();
                    i /= num.get_i();
                    assign(i);
                }
                else if (s_intdiv_type == Number::FLOATING)
                {
                    if (b_mp::fmod(to_f(), num.to_f()) != 0)
                    {
                        f = to_f();
                        f /= num.to_f();
                        assign(f);
                    }
                    else
                    {
                        i = get_i();
                        i /= num.get_i();
                        assign(i);
                    }
                }
                else if (s_intdiv_type == Number::RATIONAL)
                {
                    r = rational_type(get_i(), num.get_i());
                    assign(r);
                }
                else
                {
                    assert(0);
                }
                break;

            case Number::FLOATING:
                f = to_f();
                f /= num.get_f();
                assign(f);
                break;

            case Number::RATIONAL:
                r = to_r();
                r /= num.get_r();
                assign(r);
                break;

            default:
                assert(0);
                break;
            }
            break;

        case Number::FLOATING:
            switch (num.type())
            {
            case Number::INTEGER:
                f = get_f();
                f /= num.to_f();
                assign(f);
                break;

            case Number::FLOATING:
                f = get_f();
                f /= num.get_f();
                assign(f);
                break;

            case Number::RATIONAL:
                f = get_f();
                f /= num.to_f();
                assign(f);
                break;

            default:
                assert(0);
                break;
            }
            break;

        case Number::RATIONAL:
            switch (num.type())
            {
            case Number::INTEGER:
                r = get_r();
                r /= num.to_r();
                assign(r);
                break;

            case Number::FLOATING:
                f = to_f();
                f /= num.get_f();
                assign(f);
                break;

            case Number::RATIONAL:
                r = get_r();
                r /= num.get_r();
                assign(r);
                break;

            default:
                assert(0);
                break;
            }
            break;

        default:
            assert(0);
            break;
        }
        return *this;
    }
示例#11
0
float remap_to_palette_floyd(read_info *input_image, write_info *output_image, const colormap *map, float min_opaque_val, int ie_bug)
{
    rgb_pixel **input_pixels = (rgb_pixel **)input_image->row_pointers;
    unsigned char **row_pointers = output_image->row_pointers;
    int rows = input_image->height, cols = input_image->width;
    double gamma = input_image->gamma;

    int remapped_pixels=0;
    float remapping_error=0;

    const colormap_item *acolormap = map->palette;

    int ind=0;
    int transparent_ind = best_color_index((f_pixel){0,0,0,0}, map, min_opaque_val, NULL);

    f_pixel *restrict thiserr = NULL;
    f_pixel *restrict nexterr = NULL;
    float sr=0, sg=0, sb=0, sa=0;
    int fs_direction = 1;

    /* Initialize Floyd-Steinberg error vectors. */
    thiserr = malloc((cols + 2) * sizeof(*thiserr));
    nexterr = malloc((cols + 2) * sizeof(*thiserr));
    srandom(12345); /** deterministic dithering is better for comparing results */

    for (int col = 0; col < cols + 2; ++col) {
        const double rand_max = RAND_MAX;
        thiserr[col].r = ((double)random() - rand_max/2.0)/rand_max/255.0;
        thiserr[col].g = ((double)random() - rand_max/2.0)/rand_max/255.0;
        thiserr[col].b = ((double)random() - rand_max/2.0)/rand_max/255.0;
        thiserr[col].a = ((double)random() - rand_max/2.0)/rand_max/255.0;
    }

    for (int row = 0; row < rows; ++row) {
        memset(nexterr, 0, (cols + 2) * sizeof(*nexterr));

        int col = (fs_direction) ? 0 : (cols - 1);

        do {
            f_pixel px = to_f(gamma, input_pixels[row][col]);

            /* Use Floyd-Steinberg errors to adjust actual color. */
            sr = px.r + thiserr[col + 1].r;
            sg = px.g + thiserr[col + 1].g;
            sb = px.b + thiserr[col + 1].b;
            sa = px.a + thiserr[col + 1].a;

            if (sr < 0) sr = 0;
            else if (sr > 1) sr = 1;
            if (sg < 0) sg = 0;
            else if (sg > 1) sg = 1;
            if (sb < 0) sb = 0;
            else if (sb > 1) sb = 1;
            if (sa < 0) sa = 0;
            /* when fighting IE bug, dithering must not make opaque areas transparent */
            else if (sa > 1 || (ie_bug && px.a > 255.0/256.0)) sa = 1;

            if (sa < 1.0/256.0) {
                ind = transparent_ind;
            } else {
                float diff;
                ind = best_color_index((f_pixel){.r=sr, .g=sg, .b=sb, .a=sa}, map, min_opaque_val, &diff);

                remapped_pixels++;
                remapping_error += diff;
            }

            row_pointers[row][col] = ind;

            float colorimp = (3.0f + acolormap[ind].acolor.a)/4.0f;
            f_pixel xp = acolormap[ind].acolor;

            f_pixel err = {
                .r = (sr - xp.r) * colorimp,
                .g = (sg - xp.g) * colorimp,
                .b = (sb - xp.b) * colorimp,
                .a = (sa - xp.a),
            };

            /* Propagate Floyd-Steinberg error terms. */
            if (fs_direction) {
                thiserr[col + 2].a += (err.a * 7.0f) / 16.0f;
                thiserr[col + 2].r += (err.r * 7.0f) / 16.0f;
                thiserr[col + 2].g += (err.g * 7.0f) / 16.0f;
                thiserr[col + 2].b += (err.b * 7.0f) / 16.0f;

                nexterr[col    ].a += (err.a * 3.0f) / 16.0f;
                nexterr[col    ].r += (err.r * 3.0f) / 16.0f;
                nexterr[col    ].g += (err.g * 3.0f) / 16.0f;
                nexterr[col    ].b += (err.b * 3.0f) / 16.0f;

                nexterr[col + 1].a += (err.a * 5.0f) / 16.0f;
                nexterr[col + 1].r += (err.r * 5.0f) / 16.0f;
                nexterr[col + 1].g += (err.g * 5.0f) / 16.0f;
                nexterr[col + 1].b += (err.b * 5.0f) / 16.0f;

                nexterr[col + 2].a += (err.a       ) / 16.0f;
                nexterr[col + 2].r += (err.r       ) / 16.0f;
                nexterr[col + 2].g += (err.g       ) / 16.0f;
                nexterr[col + 2].b += (err.b       ) / 16.0f;
            } else {
                thiserr[col    ].a += (err.a * 7.0f) / 16.0f;
                thiserr[col    ].r += (err.r * 7.0f) / 16.0f;
                thiserr[col    ].g += (err.g * 7.0f) / 16.0f;
                thiserr[col    ].b += (err.b * 7.0f) / 16.0f;

                nexterr[col    ].a += (err.a       ) / 16.0f;
                nexterr[col    ].r += (err.r       ) / 16.0f;
                nexterr[col    ].g += (err.g       ) / 16.0f;
                nexterr[col    ].b += (err.b       ) / 16.0f;

                nexterr[col + 1].a += (err.a * 5.0f) / 16.0f;
                nexterr[col + 1].r += (err.r * 5.0f) / 16.0f;
                nexterr[col + 1].g += (err.g * 5.0f) / 16.0f;
                nexterr[col + 1].b += (err.b * 5.0f) / 16.0f;

                nexterr[col + 2].a += (err.a * 3.0f) / 16.0f;
                nexterr[col + 2].r += (err.r * 3.0f) / 16.0f;
                nexterr[col + 2].g += (err.g * 3.0f) / 16.0f;
                nexterr[col + 2].b += (err.b * 3.0f) / 16.0f;
            }

            if (fs_direction) {
                ++col;
                if (col >= cols) break;
            } else {
                --col;
                if (col < 0) break;
            }
        }
        while(1);

        f_pixel *temperr;
        temperr = thiserr;
        thiserr = nexterr;
        nexterr = temperr;
        fs_direction = !fs_direction;
    }

    return remapping_error / MAX(1, remapped_pixels);
}