void rescale_images_fillbitmap(gfxfilter_t*dev, gfxline_t*line, gfximage_t*img, gfxmatrix_t*matrix, gfxcxform_t*cxform, gfxdevice_t*out)
{
    internal_t*i = (internal_t*)dev->internal;

    if(img->width<=0 || img->height<=0)
        return;

    int target_width = (int)(sqrt(matrix->m00*matrix->m00 + matrix->m01*matrix->m01)*img->width);
    int target_height = (int)(sqrt(matrix->m10*matrix->m10 + matrix->m11*matrix->m11)*img->height);

    int new_width = (int)ceil(target_width*i->config_subpixels);
    int new_height = (int)ceil(target_height*i->config_subpixels);

    if(new_width<=0)
	new_width = 1;
    if(new_height<=0)
	new_height = 1;

    if(new_width < img->width || new_height < img->height) {
	msg("<verbose> Scaling %dx%d image to %dx%d", img->width, img->height, new_width, new_height);
	gfximage_t*new_image = gfximage_rescale(img, new_width, new_height);
        gfxmatrix_t m = *matrix;
        m.m00 = (m.m00 * img->width) / new_width;
        m.m01 = (m.m01 * img->width) / new_width;
        m.m10 = (m.m10 * img->height) / new_height;
        m.m11 = (m.m11 * img->height) / new_height;
        out->fillbitmap(out, line, new_image, &m, cxform);
        gfximage_free(new_image);
    } else {
        out->fillbitmap(out, line, img, matrix, cxform);
    }
}
示例#2
0
void pdf_fillbitmap(gfxdevice_t*dev, gfxline_t*line, gfximage_t*img, gfxmatrix_t*matrix, gfxcxform_t*cxform)
{
    internal_t*i = (internal_t*)dev->internal;

    int t,size=img->width*img->height;
    int has_alpha=0;
    for(t=0;t<size;t++) {
	if(img->data[t].a!=255) {
	    has_alpha=1;
	    break;
	}
    }

    double w = sqrt(matrix->m00*matrix->m00+matrix->m01*matrix->m01);
    double h = sqrt(matrix->m10*matrix->m10+matrix->m11*matrix->m11);
    double l1 = w*img->width;
    double l2 = h*img->height;

    double dpi_x = 72.0 / w;
    double dpi_y = 72.0 / h;
    double dpi = dpi_x>dpi_y?dpi_x:dpi_y;
    gfximage_t*rescaled_image = 0;
    if(i->config_maxdpi && dpi > i->config_maxdpi) {
	int newwidth = img->width*i->config_maxdpi/dpi;
	int newheight = img->height*i->config_maxdpi/dpi;
	rescaled_image = gfximage_rescale(img, newwidth, newheight);
	msg("<notice> Downscaling %dx%d image (dpi %f, %.0fx%.0f on page) to %dx%d (dpi %d)", 
		img->width, img->height, dpi, l1, l2, newwidth, newheight, i->config_maxdpi);
	img = rescaled_image;
    }
    if(i->config_mindpi && dpi < i->config_mindpi && img->width>1 && img->height>1) {
	msg("<error> Found image of size %dx%d with dpi %f, minimum allowed dpi is %d", 
		img->width, img->height, dpi, i->config_mindpi);
	exit(1);
    }

    char tempfile[128];
    mktempname(tempfile, "jpg");

    gfximage_save_jpeg(img, tempfile, 96);

    int imgid=-1;
    if(has_alpha) {
	char tempfile2[128];
	mktempname(tempfile2, "jpg");
	int t;
	int size = img->width*img->height;
	unsigned char*alpha = malloc(size);
	for(t=0;t<size;t++) {
	    alpha[t] = img->data[t].a;
	}
	jpeg_save_gray(alpha, img->width, img->height, 97, tempfile2);
	free(alpha);
	int maskid = PDF_load_image(i->p, "jpeg", tempfile2, 0, "mask");
	unlink(tempfile2);
	char masked[80];
	if(maskid<0) {
	    msg("<error> Couldn't process mask jpeg of size %dx%d: error code %d", img->width, img->height, maskid);
	    return;
	}
	sprintf(masked, "masked %d", maskid);
	imgid = PDF_load_image(i->p, "jpeg", tempfile, 0, masked);
    } else {
	imgid = PDF_load_image(i->p, "jpeg", tempfile, 0, "");
    }

    if(imgid<0) {
	msg("<error> Couldn't process jpeg of size %dx%d: error code %d, file %s", img->width, img->height, imgid, tempfile);
	return;
    }
    unlink(tempfile);
    
    char options[80];
    set_matrix(i, matrix->m00, matrix->m01, matrix->m10, matrix->m11);
    /* an image's (0,0) is at the lower left corner */
    double x=matrix->tx + i->config_xpad + matrix->m10*img->height;
    double y=matrix->ty + i->config_ypad + matrix->m11*img->height;
    double tx,ty;
    transform_back(i, x, y, &tx, &ty);
    PDF_place_image(i->p, imgid, tx, ty, 1.0);
    PDF_close_image(i->p, imgid);

    if(rescaled_image)
	gfximage_free(rescaled_image);
}