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); } }
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); }