示例#1
0
/* Return gs_error_undefinedresult if the matrix is not invertible. */
int
gs_point_transform_inverse(floatp x, floatp y, const gs_matrix * pmat,
                           gs_point * ppt)
{
    if (is_xxyy(pmat)) {
        if (is_fzero(pmat->xx) || is_fzero(pmat->yy))
            return_error(gs_error_undefinedresult);
        ppt->x = (x - pmat->tx) / pmat->xx;
        ppt->y = (y - pmat->ty) / pmat->yy;
        return 0;
    } else if (is_xyyx(pmat)) {
        if (is_fzero(pmat->xy) || is_fzero(pmat->yx))
            return_error(gs_error_undefinedresult);
        ppt->x = (y - pmat->ty) / pmat->xy;
        ppt->y = (x - pmat->tx) / pmat->yx;
        return 0;
    } else {			/* There are faster ways to do this, */
        /* but we won't implement one unless we have to. */
        gs_matrix imat;
        int code = gs_matrix_invert(pmat, &imat);

        if (code < 0)
            return code;
        return gs_point_transform(x, y, &imat, ppt);
    }
}
示例#2
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;
}
示例#3
0
static int
ctm_set_inverse(gs_state * pgs)
{
    int code = gs_matrix_invert(&ctm_only(pgs), &pgs->ctm_inverse);

    print_inverse(pgs);
    if (code < 0)
        return code;
    pgs->ctm_inverse_valid = true;
    return 0;
}
示例#4
0
RELOC_PTRS_END

static int
is_image_visible(const gs_image_common_t * pic, gs_state * pgs, gx_clip_path *pcpath)
{
    /* HACK : We need the source image size here, 
       but gs_image_common_t doesn't pass it.
       We would like to move Width, Height to gs_image_common,
       but gs_image2_t appears to have those fields of double type.
     */
    if (pic->type->begin_typed_image == gx_begin_image1) {
	gs_image1_t *pim = (gs_image1_t *) pic;
	gs_rect image_rect = {{0, 0}, {0, 0}};
	gs_rect device_rect;
	gs_int_rect device_int_rect;
	gs_matrix mat;
	int code;

	image_rect.q.x = pim->Width;
	image_rect.q.y = pim->Height;
	if (pic->ImageMatrix.xx == ctm_only(pgs).xx &&
            pic->ImageMatrix.xy == ctm_only(pgs).xy &&
            pic->ImageMatrix.yx == ctm_only(pgs).yx &&
            pic->ImageMatrix.yy == ctm_only(pgs).yy) {
            /* Handle common special case separately to accept singular matrix */
            mat.xx = mat.yy = 1.;
            mat.yx = mat.xy = 0.;
            mat.tx = ctm_only(pgs).tx - pic->ImageMatrix.tx;
            mat.ty = ctm_only(pgs).ty - pic->ImageMatrix.ty;
        } else {
	code = gs_matrix_invert(&pic->ImageMatrix, &mat);
	if (code < 0)
	    return code;
	code = gs_matrix_multiply(&mat, &ctm_only(pgs), &mat);
	if (code < 0)
	    return code;
        }
	code = gs_bbox_transform(&image_rect, &mat, &device_rect);
	if (code < 0)
	    return code;
	device_int_rect.p.x = (int)floor(device_rect.p.x);
	device_int_rect.p.y = (int)floor(device_rect.p.y);
	device_int_rect.q.x = (int)ceil(device_rect.q.x);
	device_int_rect.q.y = (int)ceil(device_rect.q.y);
	if (!gx_cpath_rect_visible(pcpath, &device_int_rect))
	    return 0;
    }
    return 1;
}
示例#5
0
/* <matrix> <inv_matrix> invertmatrix <inv_matrix> */
static int
zinvertmatrix(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    gs_matrix m;
    int code;

    if ((code = read_matrix(imemory, op - 1, &m)) < 0 ||
        (code = gs_matrix_invert(&m, &m)) < 0 ||
        (code = write_matrix(op, &m)) < 0
        )
        return code;
    op[-1] = *op;
    pop(1);
    return code;
}
示例#6
0
文件: pxvendor.c 项目: hackqiang/gs
static int
vu_begin_image(px_state_t * pxs)
{
    px_vendor_state_t *v_state = pxs->vendor_state;
    gs_image_t image = v_state->image;
    px_bitmap_params_t params;
    gs_point origin;
    int code;

    if (v_state->color_space == eGraySub)
	params.color_space = eGray;
    else
	params.color_space = eSRGB;
    params.width = params.dest_width = v_state->SourceWidth;
    params.height = params.dest_height = v_state->BlockHeight;
    params.depth = 8;
    params.indexed = false;
    code = px_image_color_space(&image, &params,
				(const gs_string *)&pxs->pxgs->palette,
				pxs->pgs);
    if (code < 0) {
	return code;
    }

    /* Set up the image parameters. */
    if (gs_currentpoint(pxs->pgs, &origin) < 0)
	return_error(errorCurrentCursorUndefined);
    image.Width = v_state->SourceWidth;
    image.Height = v_state->BlockHeight;
    {
	gs_matrix imat, dmat;

	gs_make_scaling(image.Width, image.Height, &imat);
	gs_make_translation(origin.x, origin.y + v_state->StartLine, &dmat);
	gs_matrix_scale(&dmat, image.Width, image.Height, &dmat);
	/* The ImageMatrix is dmat' * imat. */
	gs_matrix_invert(&dmat, &dmat);
	gs_matrix_multiply(&dmat, &imat, &image.ImageMatrix);
    }
    image.CombineWithColor = true;
    image.Interpolate = pxs->interpolate;
    code = pl_begin_image(pxs->pgs, &image, &v_state->info);
    if (code < 0)
	return code;
    return 0;
}
示例#7
0
static int
bbox_image_begin(const gs_imager_state * pis, const gs_matrix * pmat,
		 const gs_image_common_t * pic, const gs_int_rect * prect,
		 const gx_clip_path * pcpath, gs_memory_t * memory,
		 bbox_image_enum ** ppbe)
{
    int code;
    gs_matrix mat;
    bbox_image_enum *pbe;

    if (pmat == 0)
	pmat = &ctm_only(pis);
    if ((code = gs_matrix_invert(&pic->ImageMatrix, &mat)) < 0 ||
	(code = gs_matrix_multiply(&mat, pmat, &mat)) < 0
	)
	return code;
    pbe = gs_alloc_struct(memory, bbox_image_enum, &st_bbox_image_enum,
			  "bbox_image_begin");
    if (pbe == 0)
	return_error(gs_error_VMerror);
    pbe->memory = memory;
    pbe->matrix = mat;
    pbe->pcpath = pcpath;
    pbe->target_info = 0;	/* in case no target */
    pbe->params_are_const = false;	/* check the first time */
    if (prect) {
	pbe->x0 = prect->p.x, pbe->x1 = prect->q.x;
	pbe->y = prect->p.y, pbe->height = prect->q.y - prect->p.y;
    } else {
	gs_int_point size;
	int code = (*pic->type->source_size) (pis, pic, &size);

	if (code < 0) {
	    gs_free_object(memory, pbe, "bbox_image_begin");
	    return code;
	}
	pbe->x0 = 0, pbe->x1 = size.x;
	pbe->y = 0, pbe->height = size.y;
    }
    *ppbe = pbe;
    return 0;
}
示例#8
0
int
gx_begin_image3_generic(gx_device * dev,
                        const gs_imager_state *pis, const gs_matrix *pmat,
                        const gs_image_common_t *pic, const gs_int_rect *prect,
                        const gx_drawing_color *pdcolor,
                        const gx_clip_path *pcpath, gs_memory_t *mem,
                        image3_make_mid_proc_t make_mid,
                        image3_make_mcde_proc_t make_mcde,
                        gx_image_enum_common_t **pinfo)
{
    const gs_image3_t *pim = (const gs_image3_t *)pic;
    gx_image3_enum_t *penum;
    gs_int_rect mask_rect, data_rect;
    gx_device *mdev = 0;
    gx_device *pcdev = 0;
    gs_image_t i_pixel, i_mask;
    gs_matrix mi_pixel, mi_mask, mat;
    gs_rect mrect;
    gs_int_point origin;
    int code;

    /* Validate the parameters. */
    if (pim->Height <= 0 || pim->MaskDict.Height <= 0)
        return_error(gs_error_rangecheck);
    switch (pim->InterleaveType) {
        default:
            return_error(gs_error_rangecheck);
        case interleave_chunky:
            if (pim->MaskDict.Width != pim->Width ||
                pim->MaskDict.Height != pim->Height ||
                pim->MaskDict.BitsPerComponent != pim->BitsPerComponent ||
                pim->format != gs_image_format_chunky
                )
                return_error(gs_error_rangecheck);
            break;
        case interleave_scan_lines:
            if (pim->MaskDict.Height % pim->Height != 0 &&
                pim->Height % pim->MaskDict.Height != 0
                )
                return_error(gs_error_rangecheck);
            /* falls through */
        case interleave_separate_source:
            if (pim->MaskDict.BitsPerComponent != 1)
                return_error(gs_error_rangecheck);
    }
    if (!check_image3_extent(pim->ImageMatrix.xx,
                             pim->MaskDict.ImageMatrix.xx) ||
        !check_image3_extent(pim->ImageMatrix.xy,
                             pim->MaskDict.ImageMatrix.xy) ||
        !check_image3_extent(pim->ImageMatrix.yx,
                             pim->MaskDict.ImageMatrix.yx) ||
        !check_image3_extent(pim->ImageMatrix.yy,
                             pim->MaskDict.ImageMatrix.yy)
        )
        return_error(gs_error_rangecheck);
    if ((code = gs_matrix_invert(&pim->ImageMatrix, &mi_pixel)) < 0 ||
        (code = gs_matrix_invert(&pim->MaskDict.ImageMatrix, &mi_mask)) < 0
        )
        return code;
    if (fabs(mi_pixel.tx - mi_mask.tx) >= 0.5 ||
        fabs(mi_pixel.ty - mi_mask.ty) >= 0.5
        )
        return_error(gs_error_rangecheck);
#ifdef DEBUG
    {
        /* Although the PLRM says that the Mask and Image *must* be the same size,  */
        /* Adobe CPSI (and other RIPS) ignore this and process anyway. Note that we */
        /* are not compatible if the Mask Height than the Data (pixel) Height. CPSI */
        /* de-interleaves the mask from the data image and stops at the Mask Height */
        /* Problem detected with Genoa 468-03 (part of file 468-01.ps)              */
        /*****           fixme: When Data Image Height > Mask Height            *****/
        gs_point ep, em;

        if ((code = gs_point_transform(pim->Width, pim->Height, &mi_pixel,
                                       &ep)) < 0 ||
            (code = gs_point_transform(pim->MaskDict.Width,
                                       pim->MaskDict.Height, &mi_mask,
                                       &em)) < 0
            )
            return code;
        if (fabs(ep.x - em.x) >= 0.5 || fabs(ep.y - em.y) >= 0.5)
            code = gs_error_rangecheck;	/* leave the check in for debug breakpoint */
    }
#endif /* DEBUG */
    penum = gs_alloc_struct(mem, gx_image3_enum_t, &st_image3_enum,
                            "gx_begin_image3");
    if (penum == 0)
        return_error(gs_error_VMerror);
    penum->num_components =
        gs_color_space_num_components(pim->ColorSpace);
    gx_image_enum_common_init((gx_image_enum_common_t *) penum,
                              (const gs_data_image_t *)pim,
                              &image3_enum_procs, dev,
                              1 + penum->num_components,
                              pim->format);
    /* Initialize pointers now in case we bail out. */
    penum->mask_data = 0;
    penum->pixel_data = 0;
    if (prect) {
        long lmw = pim->MaskDict.Width, lmh = pim->MaskDict.Height;

        data_rect = *prect;
        mask_rect.p.x = (int)(data_rect.p.x * lmw / pim->Width);
        mask_rect.p.y = (int)(data_rect.p.y * lmh / pim->Height);
        mask_rect.q.x = (int)((data_rect.q.x + pim->Width - 1) * lmw /
                              pim->Width);
        mask_rect.q.y = (int)((data_rect.q.y + pim->Height - 1) * lmh /
                              pim->Height);
    } else {
        mask_rect.p.x = mask_rect.p.y = 0;
        mask_rect.q.x = pim->MaskDict.Width;
        mask_rect.q.y = pim->MaskDict.Height;
        data_rect.p.x = data_rect.p.y = 0;
        data_rect.q.x = pim->Width;
        data_rect.q.y = pim->Height;
    }
    penum->mask_width = mask_rect.q.x - mask_rect.p.x;
    penum->mask_height = mask_rect.q.y - mask_rect.p.y;
    penum->mask_full_height = pim->MaskDict.Height;
    penum->mask_y = 0;
    penum->mask_skip = 0;
    penum->pixel_width = data_rect.q.x - data_rect.p.x;
    penum->pixel_height = data_rect.q.y - data_rect.p.y;
    penum->pixel_full_height = pim->Height;
    penum->pixel_y = 0;
    penum->mask_info = 0;
    penum->pixel_info = 0;
    if (pim->InterleaveType == interleave_chunky) {
        /* Allocate row buffers for the mask and pixel data. */
        penum->pixel_data =
            gs_alloc_bytes(mem,
                           (penum->pixel_width * pim->BitsPerComponent *
                            penum->num_components + 7) >> 3,
                           "gx_begin_image3(pixel_data)");
        penum->mask_data =
            gs_alloc_bytes(mem, (penum->mask_width + 7) >> 3,
                           "gx_begin_image3(mask_data)");
        if (penum->pixel_data == 0 || penum->mask_data == 0) {
            code = gs_note_error(gs_error_VMerror);
            goto out1;
        }
    }