Esempio n. 1
0
static void
ditherRow(struct pam *           const inpamP,
          const tuple *          const inrow,
          const scaler *         const scalerP,
          unsigned int **        const ditherMatrix,
          unsigned int           const ditherMatrixArea,
          struct colorResolution const colorRes,
          unsigned int           const row,
          unsigned int           const modMask,
          struct pam *           const outpamP,
          tuple *                const outrow) {

    unsigned int col;

    for (col = 0; col < inpamP->width; ++col) {
        unsigned int const d =
            ditherMatrix[row & modMask][(inpamP->width-col-1) & modMask];

        unsigned int dithered[3];
        unsigned int plane;

        assert(inpamP->depth >= 3);

        for (plane = 0; plane < 3; ++plane)
            dithered[plane] =
                dither(inrow[col][plane], inpamP->maxval, d,
                       colorRes.c[plane]-1, ditherMatrixArea);

        pnm_assigntuple(outpamP,
                        outrow[col],
                        scaler_scale(scalerP,
                                     dithered[PAM_RED_PLANE],
                                     dithered[PAM_GRN_PLANE],
                                     dithered[PAM_BLU_PLANE]));
    }
}
Esempio n. 2
0
SDL_Texture* tcache_get(surface *sur,
                        screen_palette *pal,
                        char *remap_table,
                        uint8_t pal_offset) {

    if(sur == NULL || sur->w == 0 || sur->h == 0 || sur->data == NULL) {
        if(sur != NULL) {
            DEBUG("Invalid surface requested from tcache: w,h = %d,%d data = %p", sur->w, sur->h, sur->data);
        } else {
            DEBUG("Invalid surface requested from tcache: w,h = %d,%d surface = %p", sur->w, sur->h, sur);
        }
        return NULL;
    }

    // Form a key
    tcache_entry_key key;
    memset(&key, 0, sizeof(tcache_entry_key));
    key.c_pal_offset = (sur->type == SURFACE_TYPE_RGBA) ? 0 : pal_offset;
    key.c_remap_table = (sur->type == SURFACE_TYPE_RGBA) ? 0 : remap_table;
    key.c_surface = sur;
    key.w = sur->w;
    key.h = sur->h;

    // Attempt to find appropriate surface
    // If surface is cacheable and hasn't changed, just return here.
    tcache_entry_value *val = tcache_get_entry(&key);
    if(val != NULL && (val->pal_version == pal->version || sur->type == SURFACE_TYPE_RGBA) && !sur->force_refresh) {
        val->age = 0;
        cache->hits++;
        return val->tex;
    }

    // Reset refresh flag here
    sur->force_refresh = 0;

    // If there was no fitting surface tex in the cache at all,
    // then we need to create one
    if(val == NULL) {
        tcache_entry_value new_entry;
        new_entry.age = 0;
        new_entry.pal_version = pal->version;
        new_entry.tex = SDL_CreateTexture(cache->renderer,
                                          SDL_PIXELFORMAT_ABGR8888,
                                          SDL_TEXTUREACCESS_STREAMING,
                                          sur->w * cache->scale_factor,
                                          sur->h * cache->scale_factor);
        SDL_SetTextureBlendMode(new_entry.tex, SDL_BLENDMODE_BLEND);
        val = tcache_add_entry(&key, &new_entry);
    }

    // We have a texture either from the cache, or we just created one.
    // Either one, it needs to be updated. Let's do it now.
    // Also, scale surface if necessary
    if(cache->scale_factor > 1) {
        char *raw = malloc(sur->w * sur->h * 4);
        surface scaled;
        surface_create(&scaled,
                       SURFACE_TYPE_RGBA,
                       sur->w * cache->scale_factor,
                       sur->h * cache->scale_factor);

        surface_to_rgba(sur, raw, pal, remap_table, pal_offset);
        scaler_scale(cache->scaler, raw, scaled.data, sur->w, sur->h, cache->scale_factor);
        surface_to_texture(&scaled, val->tex, pal, remap_table, pal_offset);
        surface_free(&scaled);
        free(raw);
    } else {
        surface_to_texture(sur, val->tex, pal, remap_table, pal_offset);
    }

    // Set correct age and palette version
    val->age = 0;
    val->pal_version = pal->version;

    // Do some statistics stuff
    cache->misses++;
    return val->tex;
}