image_init_colors(gx_image_enum * penum, int bps, int spp,
                  gs_image_format_t format, const float *decode /*[spp*2] */ ,
                  const gs_gstate * pgs, gx_device * dev,
                  const gs_color_space * pcs, bool * pdcb)
{
    int ci, decode_type, code;
    static const float default_decode[] = {
        0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0
    };

    /* Clues are only used with image_mono_render */
    if (spp == 1) {
        image_init_clues(penum, bps, spp);
    }
    decode_type = 3; /* 0=custom, 1=identity, 2=inverted, 3=impossible */
    for (ci = 0; ci < spp; ci +=2 ) {
        decode_type &= (decode[ci] == 0. && decode[ci + 1] == 1.) |
                       (decode[ci] == 1. && decode[ci + 1] == 0.) << 1;
    }

    /* Initialize the maps from samples to intensities. */
    for (ci = 0; ci < spp; ci++) {
        sample_map *pmap = &penum->map[ci];

        /* If the decoding is [0 1] or [1 0], we can fold it */
        /* into the expansion of the sample values; */
        /* otherwise, we have to use the floating point method. */

        const float *this_decode = &decode[ci * 2];
        const float *map_decode;        /* decoding used to */
                                        /* construct the expansion map */
        const float *real_decode;       /* decoding for expanded samples */

        map_decode = real_decode = this_decode;
        if (!(decode_type & 1)) {
            if ((decode_type & 2) && bps <= 8) {
                real_decode = default_decode;
            } else {
                *pdcb = false;
                map_decode = default_decode;
            }
        }
        if (bps > 2 || format != gs_image_format_chunky) {
            if (bps <= 8)
                image_init_map(&pmap->table.lookup8[0], 1 << bps,
                               map_decode);
        } else {                /* The map index encompasses more than one pixel. */
            byte map[4];
            register int i;

            image_init_map(&map[0], 1 << bps, map_decode);
            switch (bps) {
                case 1:
                    {
                        register bits32 *p = &pmap->table.lookup4x1to32[0];

                        if (map[0] == 0 && map[1] == 0xff)
                            memcpy((byte *) p, lookup4x1to32_identity, 16 * 4);
                        else if (map[0] == 0xff && map[1] == 0)
                            memcpy((byte *) p, lookup4x1to32_inverted, 16 * 4);
                        else
                            for (i = 0; i < 16; i++, p++)
                                ((byte *) p)[0] = map[i >> 3],
                                    ((byte *) p)[1] = map[(i >> 2) & 1],
                                    ((byte *) p)[2] = map[(i >> 1) & 1],
                                    ((byte *) p)[3] = map[i & 1];
                    }
                    break;
                case 2:
                    {
                        register bits16 *p = &pmap->table.lookup2x2to16[0];

                        for (i = 0; i < 16; i++, p++)
                            ((byte *) p)[0] = map[i >> 2],
                                ((byte *) p)[1] = map[i & 3];
                    }
                    break;
            }
        }
        pmap->decode_base /* = decode_lookup[0] */  = real_decode[0];
        pmap->decode_factor =
            (real_decode[1] - real_decode[0]) /
            (bps <= 8 ? 255.0 : (float)frac_1);
        pmap->decode_max /* = decode_lookup[15] */  = real_decode[1];
        if (decode_type) {
            pmap->decoding = sd_none;
            pmap->inverted = map_decode[0] != 0;
        } else if (bps <= 4) {
            int step = 15 / ((1 << bps) - 1);
            int i;

            pmap->decoding = sd_lookup;
            for (i = 15 - step; i > 0; i -= step)
                pmap->decode_lookup[i] = pmap->decode_base +
                    i * (255.0 / 15) * pmap->decode_factor;
            pmap->inverted = 0;
        } else {
            pmap->decoding = sd_compute;
            pmap->inverted = 0;
        }
        if (spp == 1) {         /* and ci == 0 *//* Pre-map entries 0 and 255. */
            gs_client_color cc;

            /* Image clues are used in this case */
            cc.paint.values[0] = real_decode[0];
            code = (*pcs->type->remap_color) (&cc, pcs, penum->icolor0,
                                       pgs, dev, gs_color_select_source);
            if (code < 0) 
                return code;
            cc.paint.values[0] = real_decode[1];
            code = (*pcs->type->remap_color) (&cc, pcs, penum->icolor1,
                                       pgs, dev, gs_color_select_source);
            if (code < 0) 
                return code;
        }
    }
    return 0;
}