示例#1
0
/*
 * Convert a CIEBasedDEFG color into device color.
 */
static int
client_remap_CIEBasedDEFG(client_custom_color_params_t * pparams,
    const gs_client_color * pc, const gs_color_space * pcs,
    gx_device_color * pdc, const gs_imager_state * pis, gx_device * dev,
    gs_color_select_t select)
{
    demo_color_space_data_t * pdata =
	(demo_color_space_data_t *)(pcs->pclient_color_space_data);
    frac cmyk[4];
    int i;

    /*** Demonstrate method to convert to XYZ ***/
    if (pdata->CIEtoXYZ_pis) {
	frac xyz[3];

	cs_concretize_color(pc, pcs, xyz, pdata->CIEtoXYZ_pis);
	/* We don't really do anything with these values, but this */
	/* is where a real client could convert to a device color  */
	if_debug7('|', "[c]client_remap CIEDEFG [%g, %g, %g] -> XYZ [%g, %g, %g]\n",
		  pc->paint.values[0], pc->paint.values[1], pc->paint.values[2],
		  pc->paint.values[3],
		  frac2float(xyz[0]), frac2float(xyz[1]), frac2float(xyz[2]));
    }
    /*
     * For demo and debug purposes, make our colors a function of the
     * intensity of the given color value and the object type.  The color
     * values could represent almost anything.  However we are assuming
     * that they are CMYK values.
     */
    for (i = 0; i < 4; i++)
	cmyk[i] = convert2frac(pc->paint.values[i],
		       	pcs->params.defg->RangeDEFG.ranges[i]);
    return client_remap_DeviceRGB(pparams, cmyk, pcs, pdc, pis, dev, select);
}
示例#2
0
/* Fill a rectangle. */
int
gz_fill_rectangle(int x, int y, int w, int h, const gx_device_color *pdevc,
  gs_state *pgs)
{	gx_device *dev = pgs->device->info;
	if_debug7('v', "[v]x=%d y=%d w=%d h=%d  c1=%ld c2=%ld htl=%d\n",
		  x, y, w, h, (long)pdevc->color1, (long)pdevc->color2,
		  (long)pdevc->halftone_level);
	return gz_fill_rectangle_open(dev, x, y, w, h, dev->procs->fill_rectangle, dev->procs->tile_rectangle, pdevc, pgs);
}
示例#3
0
/* This is the second half of gs_screen_init_accurate. */
int
gs_screen_enum_init_memory(gs_screen_enum * penum, const gx_ht_order * porder,
                           gs_state * pgs, const gs_screen_halftone * phsp,
                           gs_memory_t * mem)
{
    penum->pgs = pgs;           /* ensure clean for GC */
    if (&penum->order != porder) /* Pacify Valgrind */
        penum->order = *porder;
    penum->halftone.rc.memory = mem;
    penum->halftone.type = ht_type_screen;
    penum->halftone.params.screen = *phsp;
    penum->x = penum->y = 0;

    if (porder->wse == NULL) {
        penum->strip = porder->num_levels / porder->width;
        penum->shift = porder->shift;
        /*
         * We want a transformation matrix that maps the parallelogram
         * (0,0), (U,V), (U-V',V+U'), (-V',U') to the square (+/-1, +/-1).
         * If the coefficients are [a b c d e f] and we let
         *      u = U = M/R, v = V = N/R,
         *      r = -V' = -N'/R', s = U' = M'/R',
         * then we just need to solve the equations:
         *      a*0 + c*0 + e = -1      b*0 + d*0 + f = -1
         *      a*u + c*v + e = 1       b*u + d*v + f = 1
         *      a*r + c*s + e = -1      b*r + d*s + f = 1
         * This has the following solution:
         *      Q = 2 / (M*M' + N*N')
         *      a = Q * R * M'
         *      b = -Q * R' * N
         *      c = Q * R * N'
         *      d = Q * R' * M
         *      e = -1
         *      f = -1
         */
        {
            const int M = porder->params.M, N = porder->params.N, R = porder->params.R;
            const int M1 = porder->params.M1, N1 = porder->params.N1, R1 = porder->params.R1;
            double Q = 2.0 / ((long)M * M1 + (long)N * N1);

            penum->mat.xx = Q * (R * M1);
            penum->mat.xy = Q * (-R1 * N);
            penum->mat.yx = Q * (R * N1);
            penum->mat.yy = Q * (R1 * M);
            penum->mat.tx = -1.0;
            penum->mat.ty = -1.0;
            gs_matrix_invert(&penum->mat, &penum->mat_inv);
        }
        if_debug7('h', "[h]Screen: (%dx%d)/%d [%f %f %f %f]\n",
                  porder->width, porder->height, porder->params.R,
                  penum->mat.xx, penum->mat.xy,
                  penum->mat.yx, penum->mat.yy);
    }
    return 0;
}
示例#4
0
/* Note that this involves black generation and undercolor removal. */
void
color_rgb_to_cmyk(frac r, frac g, frac b, const gs_imager_state * pis,
                  frac cmyk[4], gs_memory_t *mem)
{
    frac c = frac_1 - r, m = frac_1 - g, y = frac_1 - b;
    frac k = (c < m ? min(c, y) : min(m, y));

    /*
     * The default UCR and BG functions are pretty arbitrary,
     * but they must agree with the ones in gs_init.ps.
     */
    frac bg =
        (pis == NULL ? k : pis->black_generation == NULL ? frac_0 :
         gx_map_color_frac(pis, k, black_generation));
    signed_frac ucr =
        (pis == NULL ? k : pis->undercolor_removal == NULL ? frac_0 :
         gx_map_color_frac(pis, k, undercolor_removal));

    if (ucr == frac_1)
        cmyk[0] = cmyk[1] = cmyk[2] = 0;
    else if (ucr == frac_0)
        cmyk[0] = c, cmyk[1] = m, cmyk[2] = y;
    else {
        if (!gs_currentcpsimode(mem)) {
            /* C = max(0.0, min(1.0, 1 - R - UCR)), etc. */
            signed_frac not_ucr = (ucr < 0 ? frac_1 + ucr : frac_1);

            cmyk[0] = (c < ucr ? frac_0 : c > not_ucr ? frac_1 : c - ucr);
            cmyk[1] = (m < ucr ? frac_0 : m > not_ucr ? frac_1 : m - ucr);
            cmyk[2] = (y < ucr ? frac_0 : y > not_ucr ? frac_1 : y - ucr);
        } else {
            /* Adobe CPSI method */
            /* C = max(0.0, min(1.0, 1 - R / (1 - UCR))), etc. */
            float denom = frac2float(frac_1 - ucr);		/* unscaled */
            float v;

            v = (float)frac_1 - r / denom;	/* unscaled */
            cmyk[0] =
                (is_fneg(v) ? frac_0 : v >= (float)frac_1 ? frac_1 : (frac) v);
            v = (float)frac_1 - g / denom;	/* unscaled */
            cmyk[1] =
                (is_fneg(v) ? frac_0 : v >= (float)frac_1 ? frac_1 : (frac) v);
            v = (float)frac_1 - b / denom;	/* unscaled */
            cmyk[2] =
                (is_fneg(v) ? frac_0 : v >= (float)frac_1 ? frac_1 : (frac) v);
        }
    }
    cmyk[3] = bg;
    if_debug7('c', "[c]RGB 0x%x,0x%x,0x%x -> CMYK 0x%x,0x%x,0x%x,0x%x\n",
              r, g, b, cmyk[0], cmyk[1], cmyk[2], cmyk[3]);
}
示例#5
0
/* Convert CMYK to RGB. */
void
color_cmyk_to_rgb(frac c, frac m, frac y, frac k, const gs_imager_state * pis,
                  frac rgb[3], gs_memory_t *mem)
{
    switch (k) {
        case frac_0:
            rgb[0] = frac_1 - c;
            rgb[1] = frac_1 - m;
            rgb[2] = frac_1 - y;
            break;
        case frac_1:
            rgb[0] = rgb[1] = rgb[2] = frac_0;
            break;
        default:
            if (!gs_currentcpsimode(mem)) {
                /* R = 1.0 - min(1.0, C + K), etc. */
                frac not_k = frac_1 - k;

                rgb[0] = (c > not_k ? frac_0 : not_k - c);
                rgb[1] = (m > not_k ? frac_0 : not_k - m);
                rgb[2] = (y > not_k ? frac_0 : not_k - y);
            } else {
                /* R = (1.0 - C) * (1.0 - K), etc. */
                ulong not_k = frac_1 - k;

                /* Compute not_k * (frac_1 - v) / frac_1 efficiently. */
                ulong prod;

#define deduct_black(v)\
  (prod = (frac_1 - (v)) * not_k, frac_1_quo(prod))
                rgb[0] = deduct_black(c);
                rgb[1] = deduct_black(m);
                rgb[2] = deduct_black(y);
#undef deduct_black
            }
    }
    if_debug7('c', "[c]CMYK 0x%x,0x%x,0x%x,0x%x -> RGB 0x%x,0x%x,0x%x\n",
              c, m, y, k, rgb[0], rgb[1], rgb[2]);
}