mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2025-12-31 03:10:13 +01:00
Allow mime image to be different size to cairo image
Previously it was assumed the mime image size is the same as the cairo image surface size. When using the 1 bpp formats (CCITT, JBIG2), creating a cairo image of the same size will have very large memory requirements and in some case may exceed the pixman image size limits. In these cases it is useful to allow the mime image to have a different resolution to the cairo image and in the PDF/PS output scale the mime image to be the same physical size as the cairo image. In PDF, this is easy as all PDF images are scaled to 1x1 unit and the CTM is used to scale the image to the required size. The PS surface has been changed to also scale images to 1x1 and use the CTM to get the required size.
This commit is contained in:
parent
e1a02b180d
commit
87dfd0c16f
2 changed files with 24 additions and 129 deletions
|
|
@ -1402,97 +1402,6 @@ _cairo_pdf_surface_release_source_image_from_pattern (cairo_pdf_surface_t
|
|||
}
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_get_jbig2_image_info (cairo_surface_t *source,
|
||||
cairo_image_info_t *info)
|
||||
{
|
||||
const unsigned char *mime_data;
|
||||
unsigned long mime_data_length;
|
||||
|
||||
cairo_surface_get_mime_data (source, CAIRO_MIME_TYPE_JBIG2,
|
||||
&mime_data, &mime_data_length);
|
||||
if (mime_data == NULL)
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
return _cairo_image_info_get_jbig2_info (info, mime_data, mime_data_length);
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_get_jpx_image_info (cairo_surface_t *source,
|
||||
cairo_image_info_t *info)
|
||||
{
|
||||
const unsigned char *mime_data;
|
||||
unsigned long mime_data_length;
|
||||
|
||||
cairo_surface_get_mime_data (source, CAIRO_MIME_TYPE_JP2,
|
||||
&mime_data, &mime_data_length);
|
||||
if (mime_data == NULL)
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
return _cairo_image_info_get_jpx_info (info, mime_data, mime_data_length);
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_get_jpeg_image_info (cairo_surface_t *source,
|
||||
cairo_image_info_t *info)
|
||||
{
|
||||
const unsigned char *mime_data;
|
||||
unsigned long mime_data_length;
|
||||
|
||||
cairo_surface_get_mime_data (source, CAIRO_MIME_TYPE_JPEG,
|
||||
&mime_data, &mime_data_length);
|
||||
if (mime_data == NULL)
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
return _cairo_image_info_get_jpeg_info (info, mime_data, mime_data_length);
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_get_ccitt_image_info (cairo_surface_t *source,
|
||||
int *width,
|
||||
int *height)
|
||||
{
|
||||
cairo_status_t status;
|
||||
const unsigned char *ccitt_data;
|
||||
unsigned long ccitt_data_len;
|
||||
const unsigned char *ccitt_params_string;
|
||||
unsigned long ccitt_params_string_len;
|
||||
char *params;
|
||||
cairo_ccitt_params_t ccitt_params;
|
||||
|
||||
cairo_surface_get_mime_data (source, CAIRO_MIME_TYPE_CCITT_FAX,
|
||||
&ccitt_data, &ccitt_data_len);
|
||||
if (unlikely (source->status))
|
||||
return source->status;
|
||||
if (ccitt_data == NULL)
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
cairo_surface_get_mime_data (source, CAIRO_MIME_TYPE_CCITT_FAX_PARAMS,
|
||||
&ccitt_params_string, &ccitt_params_string_len);
|
||||
if (unlikely (source->status))
|
||||
return source->status;
|
||||
if (ccitt_params_string == NULL)
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
/* ensure params_string is null terminated */
|
||||
params = malloc (ccitt_params_string_len + 1);
|
||||
memcpy (params, ccitt_params_string, ccitt_params_string_len);
|
||||
params[ccitt_params_string_len] = 0;
|
||||
status = _cairo_tag_parse_ccitt_params (params, &ccitt_params);
|
||||
if (unlikely(status))
|
||||
return source->status;
|
||||
|
||||
free (params);
|
||||
|
||||
if (ccitt_params.columns <= 0 || ccitt_params.rows <= 0)
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
*width = ccitt_params.columns;
|
||||
*height = ccitt_params.rows;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_get_source_surface_extents (cairo_surface_t *source,
|
||||
cairo_rectangle_int_t *extents,
|
||||
|
|
@ -1500,8 +1409,6 @@ _get_source_surface_extents (cairo_surface_t *source,
|
|||
cairo_bool_t *subsurface)
|
||||
{
|
||||
cairo_int_status_t status;
|
||||
cairo_image_info_t info;
|
||||
int width, height;
|
||||
|
||||
*bounded = TRUE;
|
||||
*subsurface = FALSE;
|
||||
|
|
@ -1534,37 +1441,6 @@ _get_source_surface_extents (cairo_surface_t *source,
|
|||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
extents->x = 0;
|
||||
extents->y = 0;
|
||||
|
||||
status = _get_jbig2_image_info (source, &info);
|
||||
if (status != CAIRO_INT_STATUS_UNSUPPORTED) {
|
||||
extents->width = info.width;
|
||||
extents->height = info.height;
|
||||
return status;
|
||||
}
|
||||
|
||||
status = _get_jpx_image_info (source, &info);
|
||||
if (status != CAIRO_INT_STATUS_UNSUPPORTED) {
|
||||
extents->width = info.width;
|
||||
extents->height = info.height;
|
||||
return status;
|
||||
}
|
||||
|
||||
status = _get_jpeg_image_info (source, &info);
|
||||
if (status != CAIRO_INT_STATUS_UNSUPPORTED) {
|
||||
extents->width = info.width;
|
||||
extents->height = info.height;
|
||||
return status;
|
||||
}
|
||||
|
||||
status = _get_ccitt_image_info (source, &width, &height);
|
||||
if (status != CAIRO_INT_STATUS_UNSUPPORTED) {
|
||||
extents->width = width;
|
||||
extents->height = height;
|
||||
return status;
|
||||
}
|
||||
|
||||
if (! _cairo_surface_get_extents (source, extents))
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
|
|
|
|||
|
|
@ -2754,7 +2754,7 @@ _cairo_ps_surface_emit_image (cairo_ps_surface_t *surface,
|
|||
}
|
||||
|
||||
_cairo_output_stream_printf (surface->stream,
|
||||
" /ImageMatrix [ 1 0 0 -1 0 %d ] def\n"
|
||||
" /ImageMatrix [ %d 0 0 %d 0 %d ] def\n"
|
||||
" end\n"
|
||||
" /MaskDict 8 dict def\n"
|
||||
" MaskDict begin\n"
|
||||
|
|
@ -2764,14 +2764,18 @@ _cairo_ps_surface_emit_image (cairo_ps_surface_t *surface,
|
|||
" /Interpolate %s def\n"
|
||||
" /BitsPerComponent 1 def\n"
|
||||
" /Decode [ 1 0 ] def\n"
|
||||
" /ImageMatrix [ 1 0 0 -1 0 %d ] def\n"
|
||||
" /ImageMatrix [ %d 0 0 %d 0 %d ] def\n"
|
||||
" end\n"
|
||||
"end\n"
|
||||
"image\n",
|
||||
ps_image->width,
|
||||
-ps_image->height,
|
||||
ps_image->height,
|
||||
ps_image->width,
|
||||
ps_image->height,
|
||||
interpolate,
|
||||
ps_image->width,
|
||||
-ps_image->height,
|
||||
ps_image->height);
|
||||
} else {
|
||||
if (!stencil_mask) {
|
||||
|
|
@ -2808,9 +2812,11 @@ _cairo_ps_surface_emit_image (cairo_ps_surface_t *surface,
|
|||
}
|
||||
|
||||
_cairo_output_stream_printf (surface->stream,
|
||||
" /ImageMatrix [ 1 0 0 -1 0 %d ] def\n"
|
||||
" /ImageMatrix [ %d 0 0 %d 0 %d ] def\n"
|
||||
"end\n"
|
||||
"%s%s\n",
|
||||
ps_image->width,
|
||||
-ps_image->height,
|
||||
ps_image->height,
|
||||
surface->use_string_datasource ? "" : "cairo_",
|
||||
stencil_mask ? "imagemask" : "image");
|
||||
|
|
@ -2936,9 +2942,11 @@ _cairo_ps_surface_emit_jpeg_image (cairo_ps_surface_t *surface,
|
|||
}
|
||||
|
||||
_cairo_output_stream_printf (surface->stream,
|
||||
" /ImageMatrix [ 1 0 0 -1 0 %d ] def\n"
|
||||
" /ImageMatrix [ %d 0 0 %d 0 %d ] def\n"
|
||||
"end\n"
|
||||
"%simage\n",
|
||||
info.width,
|
||||
-info.height,
|
||||
info.height,
|
||||
surface->use_string_datasource ? "" : "cairo_");
|
||||
|
||||
|
|
@ -3077,9 +3085,11 @@ _cairo_ps_surface_emit_ccitt_image (cairo_ps_surface_t *surface,
|
|||
" >> /CCITTFaxDecode filter\n");
|
||||
|
||||
_cairo_output_stream_printf (surface->stream,
|
||||
" /ImageMatrix [ 1 0 0 -1 0 %d ]\n"
|
||||
" /ImageMatrix [ %d 0 0 %d 0 %d ]\n"
|
||||
">>\n"
|
||||
"%s%s\n",
|
||||
ccitt_params.columns,
|
||||
-ccitt_params.rows,
|
||||
ccitt_params.rows,
|
||||
surface->use_string_datasource ? "" : "cairo_",
|
||||
stencil_mask ? "imagemask" : "image");
|
||||
|
|
@ -3407,6 +3417,7 @@ _cairo_ps_surface_paint_surface (cairo_ps_surface_t *surface,
|
|||
{
|
||||
cairo_matrix_translate (&ps_p2d, 0.0, src_surface_extents.height);
|
||||
cairo_matrix_scale (&ps_p2d, 1.0, -1.0);
|
||||
cairo_matrix_scale (&ps_p2d, src_surface_extents.width, src_surface_extents.height);
|
||||
}
|
||||
|
||||
if (! _cairo_matrix_is_identity (&ps_p2d)) {
|
||||
|
|
@ -3545,6 +3556,14 @@ _cairo_ps_surface_emit_surface_pattern (cairo_ps_surface_t *surface,
|
|||
pattern_extents.x, pattern_extents.y,
|
||||
pattern_extents.width, pattern_extents.height);
|
||||
|
||||
|
||||
if (((cairo_surface_pattern_t *)pattern)->surface->type != CAIRO_SURFACE_TYPE_RECORDING)
|
||||
{
|
||||
_cairo_output_stream_printf (surface->stream,
|
||||
"[ %d 0 0 %d 0 0 ] concat\n",
|
||||
pattern_extents.width, pattern_extents.height);
|
||||
}
|
||||
|
||||
old_use_string_datasource = surface->use_string_datasource;
|
||||
surface->use_string_datasource = TRUE;
|
||||
if (op == CAIRO_OPERATOR_SOURCE) {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue