static fz_shade * pdf_load_shading_dict(pdf_document *xref, pdf_obj *dict, fz_matrix transform) { fz_shade *shade = NULL; pdf_function *func[FZ_MAX_COLORS] = { NULL }; pdf_obj *obj; int funcs = 0; int type = 0; int i; fz_context *ctx = xref->ctx; fz_var(shade); fz_var(func); fz_var(funcs); fz_var(type); fz_try(ctx) { shade = fz_malloc_struct(ctx, fz_shade); FZ_INIT_STORABLE(shade, 1, fz_free_shade_imp); shade->type = FZ_MESH; shade->use_background = 0; shade->use_function = 0; shade->matrix = transform; shade->bbox = fz_infinite_rect; shade->extend[0] = 0; shade->extend[1] = 0; shade->mesh_len = 0; shade->mesh_cap = 0; shade->mesh = NULL; shade->colorspace = NULL; funcs = 0; obj = pdf_dict_gets(dict, "ShadingType"); type = pdf_to_int(obj); obj = pdf_dict_gets(dict, "ColorSpace"); if (!obj) fz_throw(ctx, "shading colorspace is missing"); shade->colorspace = pdf_load_colorspace(xref, obj); /* RJW: "cannot load colorspace (%d %d R)", pdf_to_num(obj), pdf_to_gen(obj) */ obj = pdf_dict_gets(dict, "Background"); if (obj) { shade->use_background = 1; for (i = 0; i < shade->colorspace->n; i++) shade->background[i] = pdf_to_real(pdf_array_get(obj, i)); } obj = pdf_dict_gets(dict, "BBox"); if (pdf_is_array(obj)) { shade->bbox = pdf_to_rect(ctx, obj); } obj = pdf_dict_gets(dict, "Function"); if (pdf_is_dict(obj)) { funcs = 1; func[0] = pdf_load_function(xref, obj); if (!func[0]) fz_throw(ctx, "cannot load shading function (%d %d R)", pdf_to_num(obj), pdf_to_gen(obj)); } else if (pdf_is_array(obj)) { funcs = pdf_array_len(obj); if (funcs != 1 && funcs != shade->colorspace->n) fz_throw(ctx, "incorrect number of shading functions"); for (i = 0; i < funcs; i++) { func[i] = pdf_load_function(xref, pdf_array_get(obj, i)); if (!func[i]) fz_throw(ctx, "cannot load shading function (%d %d R)", pdf_to_num(obj), pdf_to_gen(obj)); } } switch (type) { case 1: pdf_load_function_based_shading(shade, xref, dict, func[0]); break; case 2: pdf_load_axial_shading(shade, xref, dict, funcs, func); break; case 3: pdf_load_radial_shading(shade, xref, dict, funcs, func); break; case 4: pdf_load_type4_shade(shade, xref, dict, funcs, func); break; case 5: pdf_load_type5_shade(shade, xref, dict, funcs, func); break; case 6: pdf_load_type6_shade(shade, xref, dict, funcs, func); break; case 7: pdf_load_type7_shade(shade, xref, dict, funcs, func); break; default: fz_throw(ctx, "unknown shading type: %d", type); } for (i = 0; i < funcs; i++) if (func[i]) pdf_drop_function(ctx, func[i]); } fz_catch(ctx) { for (i = 0; i < funcs; i++) if (func[i]) pdf_drop_function(ctx, func[i]); fz_drop_shade(ctx, shade); fz_throw(ctx, "cannot load shading type %d (%d %d R)", type, pdf_to_num(dict), pdf_to_gen(dict)); } return shade; }
static fz_error pdf_load_shading_dict(fz_shade **shadep, pdf_xref *xref, fz_obj *dict, fz_matrix transform) { fz_error error; fz_shade *shade; pdf_function *func[FZ_MAX_COLORS] = { NULL }; fz_stream *stream = NULL; fz_obj *obj; int funcs; int type; int i; shade = fz_malloc(sizeof(fz_shade)); shade->refs = 1; shade->type = FZ_MESH; shade->use_background = 0; shade->use_function = 0; shade->matrix = transform; shade->bbox = fz_infinite_rect; shade->extend[0] = 0; shade->extend[1] = 0; shade->mesh_len = 0; shade->mesh_cap = 0; shade->mesh = NULL; shade->colorspace = NULL; funcs = 0; obj = fz_dict_gets(dict, "ShadingType"); type = fz_to_int(obj); obj = fz_dict_gets(dict, "ColorSpace"); if (!obj) { fz_drop_shade(shade); return fz_throw("shading colorspace is missing"); } error = pdf_load_colorspace(&shade->colorspace, xref, obj); if (error) { fz_drop_shade(shade); return fz_rethrow(error, "cannot load colorspace (%d %d R)", fz_to_num(obj), fz_to_gen(obj)); } obj = fz_dict_gets(dict, "Background"); if (obj) { shade->use_background = 1; for (i = 0; i < shade->colorspace->n; i++) shade->background[i] = fz_to_real(fz_array_get(obj, i)); } obj = fz_dict_gets(dict, "BBox"); if (fz_is_array(obj)) { shade->bbox = pdf_to_rect(obj); } obj = fz_dict_gets(dict, "Function"); if (fz_is_dict(obj)) { funcs = 1; error = pdf_load_function(&func[0], xref, obj); if (error) { error = fz_rethrow(error, "cannot load shading function (%d %d R)", fz_to_num(obj), fz_to_gen(obj)); goto cleanup; } } else if (fz_is_array(obj)) { funcs = fz_array_len(obj); if (funcs != 1 && funcs != shade->colorspace->n) { error = fz_throw("incorrect number of shading functions"); goto cleanup; } for (i = 0; i < funcs; i++) { error = pdf_load_function(&func[i], xref, fz_array_get(obj, i)); if (error) { error = fz_rethrow(error, "cannot load shading function (%d %d R)", fz_to_num(obj), fz_to_gen(obj)); goto cleanup; } } } if (type >= 4 && type <= 7) { error = pdf_open_stream(&stream, xref, fz_to_num(dict), fz_to_gen(dict)); if (error) { error = fz_rethrow(error, "cannot open shading stream (%d %d R)", fz_to_num(dict), fz_to_gen(dict)); goto cleanup; } } switch (type) { case 1: pdf_load_function_based_shading(shade, xref, dict, func[0]); break; case 2: pdf_load_axial_shading(shade, xref, dict, funcs, func); break; case 3: pdf_load_radial_shading(shade, xref, dict, funcs, func); break; case 4: pdf_load_type4_shade(shade, xref, dict, funcs, func, stream); break; case 5: pdf_load_type5_shade(shade, xref, dict, funcs, func, stream); break; case 6: pdf_load_type6_shade(shade, xref, dict, funcs, func, stream); break; case 7: pdf_load_type7_shade(shade, xref, dict, funcs, func, stream); break; default: error = fz_throw("unknown shading type: %d", type); goto cleanup; } if (stream) fz_close(stream); for (i = 0; i < funcs; i++) if (func[i]) pdf_drop_function(func[i]); *shadep = shade; return fz_okay; cleanup: if (stream) fz_close(stream); for (i = 0; i < funcs; i++) if (func[i]) pdf_drop_function(func[i]); fz_drop_shade(shade); return fz_rethrow(error, "cannot load shading type %d (%d %d R)", type, fz_to_num(dict), fz_to_gen(dict)); }