diff options
32 files changed, 282 insertions, 167 deletions
diff --git a/include/mupdf/fitz/document.h b/include/mupdf/fitz/document.h index 70529329..a94aa53f 100644 --- a/include/mupdf/fitz/document.h +++ b/include/mupdf/fitz/document.h @@ -167,7 +167,7 @@ typedef void (fz_page_control_separation_fn)(fz_context *ctx, fz_page *page, int /* fz_page_separation_disabled_fn: Type for a function to detect whether a given separation is enabled or disabled on a page. - See fz_separation_disabled for more information. + See FZ_SEPARATION_DISABLED for more information. */ typedef int (fz_page_separation_disabled_fn)(fz_context *ctx, fz_page *page, int separation); diff --git a/include/mupdf/fitz/pixmap.h b/include/mupdf/fitz/pixmap.h index 45e12b03..16217578 100644 --- a/include/mupdf/fitz/pixmap.h +++ b/include/mupdf/fitz/pixmap.h @@ -6,6 +6,7 @@ #include "mupdf/fitz/geometry.h" #include "mupdf/fitz/store.h" #include "mupdf/fitz/colorspace.h" +#include "mupdf/fitz/separation.h" /* Pixmaps represent a set of pixels for a 2 dimensional region of a @@ -51,12 +52,14 @@ int fz_pixmap_y(fz_context *ctx, fz_pixmap *pix); h: The height of the pixmap (in pixels) + seps: Details of separations. + alpha: 0 for no alpha, 1 for alpha. Returns a pointer to the new pixmap. Throws exception on failure to allocate. */ -fz_pixmap *fz_new_pixmap(fz_context *ctx, fz_colorspace *cs, int w, int h, int alpha); +fz_pixmap *fz_new_pixmap(fz_context *ctx, fz_colorspace *cs, int w, int h, fz_separations *seps, int alpha); /* fz_new_pixmap_with_bbox: Create a pixmap of a given size, @@ -72,12 +75,14 @@ fz_pixmap *fz_new_pixmap(fz_context *ctx, fz_colorspace *cs, int w, int h, int a bbox: Bounding box specifying location/size of created pixmap. + seps: Details of separations. + alpha: 0 for no alpha, 1 for alpha. Returns a pointer to the new pixmap. Throws exception on failure to allocate. */ -fz_pixmap *fz_new_pixmap_with_bbox(fz_context *ctx, fz_colorspace *colorspace, const fz_irect *bbox, int alpha); +fz_pixmap *fz_new_pixmap_with_bbox(fz_context *ctx, fz_colorspace *colorspace, const fz_irect *bbox, fz_separations *seps, int alpha); /* fz_new_pixmap_with_data: Create a new pixmap, with its origin at @@ -90,6 +95,8 @@ fz_pixmap *fz_new_pixmap_with_bbox(fz_context *ctx, fz_colorspace *colorspace, c h: The height of the pixmap (in pixels) + seps: Details of separations. + alpha: 0 for no alpha, 1 for alpha. stride: The byte offset from the pixel data in a row to the pixel @@ -100,7 +107,7 @@ fz_pixmap *fz_new_pixmap_with_bbox(fz_context *ctx, fz_colorspace *colorspace, c Returns a pointer to the new pixmap. Throws exception on failure to allocate. */ -fz_pixmap *fz_new_pixmap_with_data(fz_context *ctx, fz_colorspace *colorspace, int w, int h, int alpha, int stride, unsigned char *samples); +fz_pixmap *fz_new_pixmap_with_data(fz_context *ctx, fz_colorspace *colorspace, int w, int h, fz_separations *seps, int alpha, int stride, unsigned char *samples); /* fz_new_pixmap_with_bbox_and_data: Create a pixmap of a given size, @@ -114,14 +121,18 @@ fz_pixmap *fz_new_pixmap_with_data(fz_context *ctx, fz_colorspace *colorspace, i colorspace: Colorspace format used for the created pixmap. The pixmap will keep a reference to the colorspace. - bbox: Bounding box specifying location/size of created pixmap. + rect: Bounding box specifying location/size of created pixmap. + + seps: Details of separations. + + alpha: Number of alpha planes (0 or 1). samples: The data block to keep the samples in. Returns a pointer to the new pixmap. Throws exception on failure to allocate. */ -fz_pixmap *fz_new_pixmap_with_bbox_and_data(fz_context *ctx, fz_colorspace *colorspace, const fz_irect *rect, int alpha, unsigned char *samples); +fz_pixmap *fz_new_pixmap_with_bbox_and_data(fz_context *ctx, fz_colorspace *colorspace, const fz_irect *rect, fz_separations *seps, int alpha, unsigned char *samples); /* fz_keep_pixmap: Take a reference to a pixmap. @@ -152,18 +163,32 @@ fz_colorspace *fz_pixmap_colorspace(fz_context *ctx, fz_pixmap *pix); /* fz_pixmap_components: Return the number of components in a pixmap. - Returns the number of components (including alpha). Does not throw exceptions. + Returns the number of components (including spots and alpha). Does not throw exceptions. */ int fz_pixmap_components(fz_context *ctx, fz_pixmap *pix); /* - fz_pixmap_components: Return the number of components in a pixmap. + fz_pixmap_colorants: Return the number of colorants in a pixmap. - Returns the number of colorants (components, less any alpha). Does not throw exceptions. + Returns the number of colorants (components, less any spots and alpha). Does not throw exceptions. */ int fz_pixmap_colorants(fz_context *ctx, fz_pixmap *pix); /* + fz_pixmap_spots: Return the number of spots in a pixmap. + + Returns the number of spots (components, less colorants and alpha). Does not throw exceptions. +*/ +int fz_pixmap_spots(fz_context *ctx, fz_pixmap *pix); + +/* + fz_pixmap_alpha: Return the number of alpha planes in a pixmap. + + Returns the number of alphas. Does not throw exceptions. +*/ +int fz_pixmap_alpha(fz_context *ctx, fz_pixmap *pix); + +/* fz_pixmap_samples: Returns a pointer to the pixel data of a pixmap. Returns the pointer. Does not throw exceptions. @@ -293,19 +318,25 @@ fz_pixmap *fz_convert_pixmap(fz_context *ctx, fz_pixmap *pix, fz_colorspace *cs_ w, h: The width and height of the region in pixels. - n: The number of color components in the image. Includes - a separate alpha channel if alpha is set. For mask images - n=1, for greyscale (plus alpha) images n=2, for rgb (plus - alpha) images n=4. + n: The number of color components in the image. + n = num composite colors + num spots + num alphas - stride: The byte offset from the data for any given pixel - to the data for the same pixel on the row below. + s: The number of spot channels in the image. alpha: 0 for no alpha, 1 for alpha present. - interpolate: A boolean flag set to non-zero if the image - will be drawn using linear interpolation, or set to zero if - image will be using nearest neighbour sampling. + flags: flag bits. + Bit 0: If set, draw the image with linear interpolation. + Bit 1: If set, free the samples buffer when the pixmap + is destroyed. + Bit 2: If set, all separations are enabled (ignore the + fields in the seps structure). + + stride: The byte offset from the data for any given pixel + to the data for the same pixel on the row below. + + seps: NULL, or a pointer to a separations structure. If NULL, + s should be 0. xres, yres: Image resolution in dpi. Default is 96 dpi. @@ -316,22 +347,26 @@ fz_pixmap *fz_convert_pixmap(fz_context *ctx, fz_pixmap *pix, fz_colorspace *cs_ the components are stored. The first n bytes are components 0 to n-1 for the pixel at (x,y). Each successive n bytes gives another pixel in scanline order. Subsequent scanlines follow on with no padding. - - free_samples: Is zero when an application has provided its own - buffer for pixel data through fz_new_pixmap_with_bbox_and_data. - If non-zero the buffer will be freed along with the pixmap. */ struct fz_pixmap_s { fz_storable storable; - int x, y, w, h, n; + int x, y, w, h; + unsigned char n; + unsigned char s; + unsigned char alpha; + unsigned char flags; ptrdiff_t stride; - int alpha; - int interpolate; + fz_separations *seps; int xres, yres; fz_colorspace *colorspace; unsigned char *samples; - int free_samples; +}; + +enum +{ + FZ_PIXMAP_FLAG_INTERPOLATE = 1, + FZ_PIXMAP_FLAG_FREE_SAMPLES = 2, }; void fz_drop_pixmap_imp(fz_context *ctx, fz_storable *pix); diff --git a/include/mupdf/fitz/separation.h b/include/mupdf/fitz/separation.h index 2f0ed596..4d17fc53 100644 --- a/include/mupdf/fitz/separation.h +++ b/include/mupdf/fitz/separation.h @@ -19,6 +19,18 @@ enum typedef struct fz_separations_s fz_separations; +typedef enum +{ + /* "Composite" separations are rendered using process + * colors using the equivalent colors */ + FZ_SEPARATION_COMPOSITE = 0, + /* Spot colors are rendered into their own spot plane. */ + FZ_SEPARATION_SPOT = 1, + /* Disabled colors are not rendered at all in the final + * output. */ + FZ_SEPARATION_DISABLED = 2 +} fz_separation_behavior; + /* Create a new separations structure (initially empty) */ fz_separations *fz_new_separations(fz_context *ctx, int controllable); @@ -31,22 +43,25 @@ void fz_drop_separations(fz_context *ctx, fz_separations *sep); /* Add a separation (RGBA and CYMK equivalents, null terminated name) */ void fz_add_separation(fz_context *ctx, fz_separations *sep, uint32_t rgba, uint32_t cmyk, const char *name); -/* Enable or disable a given separation */ -void fz_control_separation(fz_context *ctx, fz_separations *sep, int separation, int disable); +/* Control the rendering of a given separation */ +void fz_set_separation_behavior(fz_context *ctx, fz_separations *sep, int separation, fz_separation_behavior behavior); -/* Test for a separation being enabled or disabled */ -int fz_separation_disabled(fz_context *ctx, fz_separations *sep, int separation); +/* Test for the current behavior of a separation */ +fz_separation_behavior fz_separation_current_behavior(fz_context *ctx, const fz_separations *sep, int separation); -/* Quick test for all separations enabled (the common case) */ -int fz_separations_all_enabled(fz_context *ctx, fz_separations *sep); +/* Quick test for all separations composite (the common case) */ +int fz_separations_all_composite(fz_context *ctx, const fz_separations *sep); /* Read separation details */ -const char *fz_get_separation(fz_context *ctx, fz_separations *sep, int separation, uint32_t *rgb, uint32_t *cmyk); +const char *fz_get_separation(fz_context *ctx, const fz_separations *sep, int separation, uint32_t *rgb, uint32_t *cmyk); /* Count the number of separations */ -int fz_count_separations(fz_context *ctx, fz_separations *sep); +int fz_count_separations(fz_context *ctx, const fz_separations *sep); /* Find out if separations are controllable. */ -int fz_separations_controllable(fz_context *ctx, fz_separations *seps); +int fz_separations_controllable(fz_context *ctx, const fz_separations *seps); + +/* Return the number of active separations. */ +int fz_count_active_separations(fz_context *ctx, const fz_separations *seps); #endif diff --git a/platform/java/mupdf_native.c b/platform/java/mupdf_native.c index 7d068d85..8adade90 100644 --- a/platform/java/mupdf_native.c +++ b/platform/java/mupdf_native.c @@ -2861,7 +2861,7 @@ newNativeAndroidDrawDevice(JNIEnv *env, jobject self, fz_context *ctx, jobject o fz_try(ctx) { - pixmap = fz_new_pixmap_with_bbox_and_data(ctx, fz_device_rgb(ctx), &bbox, 1, &dummy); + pixmap = fz_new_pixmap_with_bbox_and_data(ctx, fz_device_rgb(ctx), &bbox, NULL, 1, &dummy); pixmap->stride = width * sizeof(int32_t); ninfo = fz_malloc(ctx, sizeof(*ninfo)); ninfo->pixmap = pixmap; @@ -2973,7 +2973,7 @@ FUN(AndroidImage_newImageFromBitmap)(JNIEnv *env, jobject self, jobject jbitmap, fz_try(ctx) { - pixmap = fz_new_pixmap(ctx, fz_device_rgb(ctx), info.width, info.height, 1); + pixmap = fz_new_pixmap(ctx, fz_device_rgb(ctx), info.width, info.height, NULL, 1); if (AndroidBitmap_lockPixels(env, jbitmap, &pixels) != ANDROID_BITMAP_RESULT_SUCCESS) fz_throw(ctx, FZ_ERROR_GENERIC, "bitmap lock failed in new Image"); memcpy(pixmap->samples, pixels, info.width * info.height * 4); @@ -3170,7 +3170,7 @@ FUN(Pixmap_newNative)(JNIEnv *env, jobject self, jobject jcs, jint x, jint y, ji fz_try(ctx) { - pixmap = fz_new_pixmap(ctx, cs, w, h, alpha); + pixmap = fz_new_pixmap(ctx, cs, w, h, NULL, alpha); pixmap->x = x; pixmap->y = y; } @@ -4223,7 +4223,7 @@ FUN(Annotation_toPixmap)(JNIEnv *env, jobject self, jobject jctm, jobject jcs, j if (!ctx || !annot) return NULL; fz_try(ctx) - pixmap = fz_new_pixmap_from_annot(ctx, annot, &ctm, cs, alpha); + pixmap = fz_new_pixmap_from_annot(ctx, annot, &ctm, cs, NULL, alpha); fz_catch(ctx) { jni_rethrow(env, ctx); @@ -4774,7 +4774,7 @@ FUN(Page_toPixmap)(JNIEnv *env, jobject self, jobject jctm, jobject jcs, jboolea if (!ctx || !page) return NULL; fz_try(ctx) - pixmap = fz_new_pixmap_from_page(ctx, page, &ctm, cs, alpha); + pixmap = fz_new_pixmap_from_page(ctx, page, &ctm, cs, NULL, alpha); fz_catch(ctx) { jni_rethrow(env, ctx); @@ -5273,7 +5273,7 @@ FUN(DisplayList_toPixmap)(JNIEnv *env, jobject self, jobject jctm, jobject jcs, if (!ctx || !list) return NULL; fz_try(ctx) - pixmap = fz_new_pixmap_from_display_list(ctx, list, &ctm, cs, alpha); + pixmap = fz_new_pixmap_from_display_list(ctx, list, &ctm, cs, NULL, alpha); fz_catch(ctx) { jni_rethrow(env, ctx); diff --git a/platform/x11/pdfapp.c b/platform/x11/pdfapp.c index 71e2ab6e..61366a44 100644 --- a/platform/x11/pdfapp.c +++ b/platform/x11/pdfapp.c @@ -922,7 +922,7 @@ static void pdfapp_showpage(pdfapp_t *app, int loadpage, int drawpage, int repai fz_try(app->ctx) { - app->image = fz_new_pixmap_with_bbox(app->ctx, colorspace, &ibounds, 1); + app->image = fz_new_pixmap_with_bbox(app->ctx, colorspace, &ibounds, NULL, 1); fz_clear_pixmap_with_value(app->ctx, app->image, 255); if (app->page_list || app->annotations_list) { @@ -950,7 +950,7 @@ static void pdfapp_showpage(pdfapp_t *app, int loadpage, int drawpage, int repai colorspace = fz_device_gray(app->ctx); else colorspace = app->colorspace; - app->image = fz_new_pixmap_with_bbox(app->ctx, colorspace, &ibounds, 1); + app->image = fz_new_pixmap_with_bbox(app->ctx, colorspace, &ibounds, NULL, 1); app->duration = 0; fz_page_presentation(app->ctx, app->page, &app->transition, &app->duration); if (app->duration == 0) diff --git a/scripts/cmapdump.c b/scripts/cmapdump.c index 8429747e..c82ac114 100644 --- a/scripts/cmapdump.c +++ b/scripts/cmapdump.c @@ -321,3 +321,17 @@ int fz_default_image_scale(void *arg, int w, int h, int src_w, int src_h) { return 0; } + +fz_separations *fz_keep_separations(fz_context *ctx, fz_separations *seps) +{ + return NULL; +} + +void fz_drop_separations(fz_context *ctx, fz_separations *seps) +{ +} + +int fz_count_active_separations(fz_context *ctx, const fz_separations *seps) +{ + return 0; +} diff --git a/source/fitz/colorspace.c b/source/fitz/colorspace.c index d9136086..61988f17 100644 --- a/source/fitz/colorspace.c +++ b/source/fitz/colorspace.c @@ -2088,7 +2088,7 @@ icc_base_conv_pixmap(fz_context *ctx, fz_pixmap *dst, fz_pixmap *src, fz_colorsp int stride_base; int bn; - base = fz_new_pixmap_with_bbox(ctx, base_cs, fz_pixmap_bbox(ctx, src, &bbox), src->alpha); + base = fz_new_pixmap_with_bbox(ctx, base_cs, fz_pixmap_bbox(ctx, src, &bbox), src->seps, src->alpha); bn = base->n; stride_base = base->stride - base->w * bn; @@ -2806,7 +2806,7 @@ fz_expand_indexed_pixmap(fz_context *ctx, const fz_pixmap *src, int alpha) lookup = idx->lookup; n = idx->base->n; - dst = fz_new_pixmap_with_bbox(ctx, idx->base, fz_pixmap_bbox(ctx, src, &bbox), alpha); + dst = fz_new_pixmap_with_bbox(ctx, idx->base, fz_pixmap_bbox(ctx, src, &bbox), src->seps, alpha); s = src->samples; d = dst->samples; s_line_inc = src->stride - src->w * src->n; @@ -2846,7 +2846,10 @@ fz_expand_indexed_pixmap(fz_context *ctx, const fz_pixmap *src, int alpha) } } - dst->interpolate = src->interpolate; + if (src->flags & FZ_PIXMAP_FLAG_INTERPOLATE) + dst->flags |= FZ_PIXMAP_FLAG_INTERPOLATE; + else + dst->flags &= ~FZ_PIXMAP_FLAG_INTERPOLATE; return dst; } diff --git a/source/fitz/draw-affine.c b/source/fitz/draw-affine.c index 866cd638..ca44be7e 100644 --- a/source/fitz/draw-affine.c +++ b/source/fitz/draw-affine.c @@ -3223,7 +3223,7 @@ fz_paint_image_imp(fz_pixmap * restrict dst, const fz_irect *scissor, const fz_p dolerp = lerp_allowed; /* except when we shouldn't, at large magnifications */ - if (!img->interpolate) + if (!(img->flags & FZ_PIXMAP_FLAG_INTERPOLATE)) { if (sqrtf(local_ctm.a * local_ctm.a + local_ctm.b * local_ctm.b) > img->w * 2) dolerp = 0; diff --git a/source/fitz/draw-device.c b/source/fitz/draw-device.c index 4dac6ee4..8c3c34e1 100644 --- a/source/fitz/draw-device.c +++ b/source/fitz/draw-device.c @@ -215,7 +215,7 @@ fz_knockout_begin(fz_context *ctx, fz_draw_device *dev) fz_pixmap_bbox(ctx, state->dest, &bbox); fz_intersect_irect(&bbox, &state->scissor); - dest = fz_new_pixmap_with_bbox(ctx, state->dest->colorspace, &bbox, state->dest->alpha || isolated); + dest = fz_new_pixmap_with_bbox(ctx, state->dest->colorspace, &bbox, state->dest->seps, state->dest->alpha || isolated); if (isolated) { @@ -246,7 +246,7 @@ fz_knockout_begin(fz_context *ctx, fz_draw_device *dev) } else { - shape = fz_new_pixmap_with_bbox(ctx, NULL, &bbox, 1); + shape = fz_new_pixmap_with_bbox(ctx, NULL, &bbox, NULL, 1); fz_clear_pixmap(ctx, shape); } #ifdef DUMP_GROUP_BLENDS @@ -506,13 +506,13 @@ fz_draw_clip_path(fz_context *ctx, fz_device *devp, const fz_path *path, int eve fz_try(ctx) { - state[1].mask = fz_new_pixmap_with_bbox(ctx, NULL, &bbox, 1); + state[1].mask = fz_new_pixmap_with_bbox(ctx, NULL, &bbox, NULL, 1); fz_clear_pixmap(ctx, state[1].mask); - state[1].dest = fz_new_pixmap_with_bbox(ctx, model, &bbox, state[0].dest->alpha); + state[1].dest = fz_new_pixmap_with_bbox(ctx, model, &bbox, state[0].dest->seps, state[0].dest->alpha); fz_copy_pixmap_rect(ctx, state[1].dest, state[0].dest, &bbox, dev->default_cs); if (state[1].shape) { - state[1].shape = fz_new_pixmap_with_bbox(ctx, NULL, &bbox, 1); + state[1].shape = fz_new_pixmap_with_bbox(ctx, NULL, &bbox, NULL, 1); fz_clear_pixmap(ctx, state[1].shape); } @@ -578,20 +578,20 @@ fz_draw_clip_stroke_path(fz_context *ctx, fz_device *devp, const fz_path *path, fz_try(ctx) { - state[1].mask = fz_new_pixmap_with_bbox(ctx, NULL, &bbox, 1); + state[1].mask = fz_new_pixmap_with_bbox(ctx, NULL, &bbox, NULL, 1); fz_clear_pixmap(ctx, state[1].mask); /* When there is no alpha in the current destination (state[0].dest->alpha == 0) * we have a choice. We can either create the new destination WITH alpha, or * we can copy the old pixmap contents in. We opt for the latter here, but * may want to revisit this decision in the future. */ - state[1].dest = fz_new_pixmap_with_bbox(ctx, model, &bbox, state[0].dest->alpha); + state[1].dest = fz_new_pixmap_with_bbox(ctx, model, &bbox, state[0].dest->seps, state[0].dest->alpha); if (state[0].dest->alpha) fz_clear_pixmap(ctx, state[1].dest); else fz_copy_pixmap_rect(ctx, state[1].dest, state[0].dest, &bbox, dev->default_cs); if (state->shape) { - state[1].shape = fz_new_pixmap_with_bbox(ctx, NULL, &bbox, 1); + state[1].shape = fz_new_pixmap_with_bbox(ctx, NULL, &bbox, NULL, 1); fz_clear_pixmap(ctx, state[1].shape); } @@ -898,20 +898,20 @@ fz_draw_clip_text(fz_context *ctx, fz_device *devp, const fz_text *text, const f fz_try(ctx) { - mask = fz_new_pixmap_with_bbox(ctx, NULL, &bbox, 1); + mask = fz_new_pixmap_with_bbox(ctx, NULL, &bbox, NULL, 1); fz_clear_pixmap(ctx, mask); /* When there is no alpha in the current destination (state[0].dest->alpha == 0) * we have a choice. We can either create the new destination WITH alpha, or * we can copy the old pixmap contents in. We opt for the latter here, but * may want to revisit this decision in the future. */ - dest = fz_new_pixmap_with_bbox(ctx, model, &bbox, state[0].dest->alpha); + dest = fz_new_pixmap_with_bbox(ctx, model, &bbox, state[0].dest->seps, state[0].dest->alpha); if (state[0].dest->alpha) fz_clear_pixmap(ctx, dest); else fz_copy_pixmap_rect(ctx, dest, state[0].dest, &bbox, dev->default_cs); if (state->shape) { - shape = fz_new_pixmap_with_bbox(ctx, NULL, &bbox, 1); + shape = fz_new_pixmap_with_bbox(ctx, NULL, &bbox, NULL, 1); fz_clear_pixmap(ctx, shape); } else @@ -1024,20 +1024,20 @@ fz_draw_clip_stroke_text(fz_context *ctx, fz_device *devp, const fz_text *text, fz_try(ctx) { - state[1].mask = mask = fz_new_pixmap_with_bbox(ctx, NULL, &bbox, 1); + state[1].mask = mask = fz_new_pixmap_with_bbox(ctx, NULL, &bbox, NULL, 1); fz_clear_pixmap(ctx, mask); /* When there is no alpha in the current destination (state[0].dest->alpha == 0) * we have a choice. We can either create the new destination WITH alpha, or * we can copy the old pixmap contents in. We opt for the latter here, but * may want to revisit this decision in the future. */ - state[1].dest = dest = fz_new_pixmap_with_bbox(ctx, model, &bbox, state[0].dest->alpha); + state[1].dest = dest = fz_new_pixmap_with_bbox(ctx, model, &bbox, state[0].dest->seps, state[0].dest->alpha); if (state[0].dest->alpha) fz_clear_pixmap(ctx, state[1].dest); else fz_copy_pixmap_rect(ctx, state[1].dest, state[0].dest, &bbox, dev->default_cs); if (state->shape) { - state[1].shape = shape = fz_new_pixmap_with_bbox(ctx, NULL, &bbox, 1); + state[1].shape = shape = fz_new_pixmap_with_bbox(ctx, NULL, &bbox, NULL, 1); fz_clear_pixmap(ctx, shape); } else @@ -1154,14 +1154,14 @@ fz_draw_fill_shade(fz_context *ctx, fz_device *devp, fz_shade *shade, const fz_m if (alpha < 1) { - dest = fz_new_pixmap_with_bbox(ctx, state->dest->colorspace, &bbox, state->dest->alpha); + dest = fz_new_pixmap_with_bbox(ctx, state->dest->colorspace, &bbox, state->dest->seps, state->dest->alpha); if (state->dest->alpha) fz_clear_pixmap(ctx, dest); else fz_copy_pixmap_rect(ctx, dest, state[0].dest, &bbox, dev->default_cs); if (shape) { - shape = fz_new_pixmap_with_bbox(ctx, NULL, &bbox, 1); + shape = fz_new_pixmap_with_bbox(ctx, NULL, &bbox, NULL, 1); fz_clear_pixmap(ctx, shape); } } @@ -1590,21 +1590,21 @@ fz_draw_clip_image_mask(fz_context *ctx, fz_device *devp, fz_image *image, const fz_try(ctx) { - state[1].mask = fz_new_pixmap_with_bbox(ctx, NULL, &bbox, 1); + state[1].mask = fz_new_pixmap_with_bbox(ctx, NULL, &bbox, NULL, 1); fz_clear_pixmap(ctx, state[1].mask); /* When there is no alpha in the current destination (state[0].dest->alpha == 0) * we have a choice. We can either create the new destination WITH alpha, or * we can copy the old pixmap contents in. We opt for the latter here, but * may want to revisit this decision in the future. */ - state[1].dest = fz_new_pixmap_with_bbox(ctx, model, &bbox, state[0].dest->alpha); + state[1].dest = fz_new_pixmap_with_bbox(ctx, model, &bbox, state[0].dest->seps, state[0].dest->alpha); if (state[0].dest->alpha) fz_clear_pixmap(ctx, state[1].dest); else fz_copy_pixmap_rect(ctx, state[1].dest, state[0].dest, &bbox, dev->default_cs); if (state[0].shape) { - state[1].shape = fz_new_pixmap_with_bbox(ctx, NULL, &bbox, 1); + state[1].shape = fz_new_pixmap_with_bbox(ctx, NULL, &bbox, NULL, 1); fz_clear_pixmap(ctx, state[1].shape); } @@ -1738,9 +1738,9 @@ fz_draw_begin_mask(fz_context *ctx, fz_device *devp, const fz_rect *rect, int lu * If !luminosity, then we generate a mask from the alpha value of the shapes. */ if (luminosity) - state[1].dest = dest = fz_new_pixmap_with_bbox(ctx, fz_device_gray(ctx), &bbox, 0); + state[1].dest = dest = fz_new_pixmap_with_bbox(ctx, fz_device_gray(ctx), &bbox, NULL, 0); else - state[1].dest = dest = fz_new_pixmap_with_bbox(ctx, NULL, &bbox, 1); + state[1].dest = dest = fz_new_pixmap_with_bbox(ctx, NULL, &bbox, NULL, 1); if (state->shape) { /* FIXME: If we ever want to support AIS true, then @@ -1823,7 +1823,7 @@ fz_draw_end_mask(fz_context *ctx, fz_device *devp) /* create new dest scratch buffer */ fz_pixmap_bbox(ctx, temp, &bbox); - dest = fz_new_pixmap_with_bbox(ctx, state->dest->colorspace, &bbox, state->dest->alpha); + dest = fz_new_pixmap_with_bbox(ctx, state->dest->colorspace, &bbox, state->dest->seps, state->dest->alpha); fz_copy_pixmap_rect(ctx, dest, state->dest, &bbox, dev->default_cs); /* push soft mask as clip mask */ @@ -1833,7 +1833,7 @@ fz_draw_end_mask(fz_context *ctx, fz_device *devp) * clip mask when we pop. So create a new shape now. */ if (state[0].shape) { - state[1].shape = fz_new_pixmap_with_bbox(ctx, NULL, &bbox, 1); + state[1].shape = fz_new_pixmap_with_bbox(ctx, NULL, &bbox, NULL, 1); fz_clear_pixmap(ctx, state[1].shape); } state[1].scissor = bbox; @@ -1872,7 +1872,7 @@ fz_draw_begin_group(fz_context *ctx, fz_device *devp, const fz_rect *rect, fz_co isolated = 1; #endif - state[1].dest = dest = fz_new_pixmap_with_bbox(ctx, model, &bbox, state[0].dest->alpha || isolated); + state[1].dest = dest = fz_new_pixmap_with_bbox(ctx, model, &bbox, state[0].dest->seps, state[0].dest->alpha || isolated); if (isolated) { @@ -1891,7 +1891,7 @@ fz_draw_begin_group(fz_context *ctx, fz_device *devp, const fz_rect *rect, fz_co } else { - state[1].shape = fz_new_pixmap_with_bbox(ctx, NULL, &bbox, 1); + state[1].shape = fz_new_pixmap_with_bbox(ctx, NULL, &bbox, NULL, 1); fz_clear_pixmap(ctx, state[1].shape); } @@ -2149,12 +2149,12 @@ fz_draw_begin_tile(fz_context *ctx, fz_device *devp, const fz_rect *area, const fz_try(ctx) { /* Patterns can be transparent, so we need to have an alpha here. */ - state[1].dest = dest = fz_new_pixmap_with_bbox(ctx, model, &bbox, 1); + state[1].dest = dest = fz_new_pixmap_with_bbox(ctx, model, &bbox, state[0].dest->seps, 1); fz_clear_pixmap(ctx, dest); shape = state[0].shape; if (shape) { - state[1].shape = shape = fz_new_pixmap_with_bbox(ctx, NULL, &bbox, 1); + state[1].shape = shape = fz_new_pixmap_with_bbox(ctx, NULL, &bbox, NULL, 1); fz_clear_pixmap(ctx, shape); } state[1].blendmode |= FZ_BLEND_ISOLATED; @@ -2632,7 +2632,7 @@ fz_new_draw_device_with_options(fz_context *ctx, const fz_draw_options *opts, co } } - *pixmap = fz_new_pixmap_with_bbox(ctx, opts->colorspace, &ibounds, opts->alpha); + *pixmap = fz_new_pixmap_with_bbox(ctx, opts->colorspace, &ibounds, NULL/* FIXME */, opts->alpha); fz_try(ctx) { fz_set_pixmap_resolution(ctx, *pixmap, opts->x_resolution, opts->y_resolution); diff --git a/source/fitz/draw-mesh.c b/source/fitz/draw-mesh.c index 10091521..2bf5f0d8 100644 --- a/source/fitz/draw-mesh.c +++ b/source/fitz/draw-mesh.c @@ -224,6 +224,7 @@ fz_paint_shade(fz_context *ctx, fz_shade *shade, const fz_matrix *ctm, fz_pixmap if (shade->use_function) { + /* FIXME */ fz_color_converter cc; int cn = fz_colorspace_n(ctx, shade->colorspace); n = fz_colorspace_n(ctx, dest->colorspace); @@ -238,8 +239,8 @@ fz_paint_shade(fz_context *ctx, fz_shade *shade, const fz_matrix *ctm, fz_pixmap fz_drop_color_converter(ctx, &cc); /* We need to use alpha = 1 here, because the shade might not fill * the bbox. */ - conv = fz_new_pixmap_with_bbox(ctx, dest->colorspace, bbox, 1); - temp = fz_new_pixmap_with_bbox(ctx, fz_device_gray(ctx), bbox, 1); + conv = fz_new_pixmap_with_bbox(ctx, dest->colorspace, bbox, NULL, 1); + temp = fz_new_pixmap_with_bbox(ctx, fz_device_gray(ctx), bbox, NULL, 1); fz_clear_pixmap(ctx, temp); } else diff --git a/source/fitz/draw-scale-simple.c b/source/fitz/draw-scale-simple.c index 725f6b1a..861afb67 100644 --- a/source/fitz/draw-scale-simple.c +++ b/source/fitz/draw-scale-simple.c @@ -1711,7 +1711,7 @@ fz_scale_pixmap_cached(fz_context *ctx, const fz_pixmap *src, float x, float y, #endif /* SINGLE_PIXEL_SPECIALS */ contrib_rows = make_weights(ctx, src->h, y, h, filter, 1, dst_h_int, patch.y0, patch.y1, src->n, flip_y, cache_y); - output = fz_new_pixmap(ctx, src->colorspace, patch.x1 - patch.x0, patch.y1 - patch.y0, src->alpha || forcealpha); + output = fz_new_pixmap(ctx, src->colorspace, patch.x1 - patch.x0, patch.y1 - patch.y0, src->seps, src->alpha || forcealpha); } fz_catch(ctx) { diff --git a/source/fitz/font.c b/source/fitz/font.c index 4c90e5f8..7a840bb5 100644 --- a/source/fitz/font.c +++ b/source/fitz/font.c @@ -1292,7 +1292,7 @@ fz_render_t3_glyph_pixmap(fz_context *ctx, fz_font *font, int gid, const fz_matr fz_intersect_irect(&bbox, scissor); /* Glyphs must always have alpha */ - glyph = fz_new_pixmap_with_bbox(ctx, model, &bbox, 1); + glyph = fz_new_pixmap_with_bbox(ctx, model, &bbox, NULL/* FIXME */, 1); fz_var(dev); fz_try(ctx) diff --git a/source/fitz/halftone.c b/source/fitz/halftone.c index 65dbcf07..7eef275f 100644 --- a/source/fitz/halftone.c +++ b/source/fitz/halftone.c @@ -76,7 +76,7 @@ fz_halftone *fz_default_halftone(fz_context *ctx, int num_comps) { int i; for (i = 0; i < num_comps; i++) - ht->comp[i] = fz_new_pixmap_with_data(ctx, NULL, 16, 16, 1, 16, mono_ht); + ht->comp[i] = fz_new_pixmap_with_data(ctx, NULL, 16, 16, NULL, 1, 16, mono_ht); } fz_catch(ctx) { diff --git a/source/fitz/image.c b/source/fitz/image.c index 6ac6fb25..89798bf2 100644 --- a/source/fitz/image.c +++ b/source/fitz/image.c @@ -264,8 +264,11 @@ fz_decomp_image_from_stream(fz_context *ctx, fz_stream *stm, fz_compressed_image int alpha = (image->colorspace == NULL); if (image->use_colorkey) alpha = 1; - tile = fz_new_pixmap(ctx, image->colorspace, w, h, alpha); - tile->interpolate = image->interpolate; + tile = fz_new_pixmap(ctx, image->colorspace, w, h, NULL, alpha); + if (image->interpolate & FZ_PIXMAP_FLAG_INTERPOLATE) + tile->flags |= FZ_PIXMAP_FLAG_INTERPOLATE; + else + tile->flags &= ~FZ_PIXMAP_FLAG_INTERPOLATE; stride = (w * image->n * image->bpc + 7) / 8; @@ -1055,13 +1058,13 @@ display_list_image_get_pixmap(fz_context *ctx, fz_image *image_, fz_irect *subar int r = (subarea->x1 * w + image->super.w - 1) / image->super.w; int b = (subarea->y1 * h + image->super.h - 1) / image->super.h; - pix = fz_new_pixmap(ctx, image->super.colorspace, r-l, b-t, 0); + pix = fz_new_pixmap(ctx, image->super.colorspace, r-l, b-t, NULL, 0); pix->x = l; pix->y = t; } else { - pix = fz_new_pixmap(ctx, image->super.colorspace, w, h, 0); + pix = fz_new_pixmap(ctx, image->super.colorspace, w, h, NULL, 0); } /* If we render the display list into pix with the image matrix, we'll get a unit diff --git a/source/fitz/load-bmp.c b/source/fitz/load-bmp.c index fabc61ed..dd852b0f 100644 --- a/source/fitz/load-bmp.c +++ b/source/fitz/load-bmp.c @@ -697,7 +697,7 @@ bmp_read_bitmap(fz_context *ctx, struct info *info, unsigned char *p, unsigned c } fz_try(ctx) - pix = fz_new_pixmap(ctx, fz_device_rgb(ctx), width, height, 1); + pix = fz_new_pixmap(ctx, fz_device_rgb(ctx), width, height, NULL, 1); fz_catch(ctx) { fz_free(ctx, decompressed); diff --git a/source/fitz/load-gif.c b/source/fitz/load-gif.c index 546bd1a8..88779e88 100644 --- a/source/fitz/load-gif.c +++ b/source/fitz/load-gif.c @@ -433,7 +433,7 @@ gif_read_image(fz_context *ctx, struct info *info, unsigned char *p, size_t tota if (only_metadata) return NULL; - pix = fz_new_pixmap(ctx, fz_device_rgb(ctx), info->width, info->height, 1); + pix = fz_new_pixmap(ctx, fz_device_rgb(ctx), info->width, info->height, NULL, 1); fz_try(ctx) { diff --git a/source/fitz/load-jpeg.c b/source/fitz/load-jpeg.c index 4a0992b7..0634f239 100644 --- a/source/fitz/load-jpeg.c +++ b/source/fitz/load-jpeg.c @@ -269,7 +269,7 @@ fz_load_jpeg(fz_context *ctx, unsigned char *rbuf, size_t rlen) else fz_throw(ctx, FZ_ERROR_GENERIC, "bad number of components in jpeg: %d", cinfo.num_components); - image = fz_new_pixmap(ctx, colorspace, cinfo.output_width, cinfo.output_height, 0); + image = fz_new_pixmap(ctx, colorspace, cinfo.output_width, cinfo.output_height, NULL, 0); if (extract_exif_resolution(cinfo.marker_list, &image->xres, &image->yres)) /* XPS prefers EXIF resolution to JFIF density */; diff --git a/source/fitz/load-jpx.c b/source/fitz/load-jpx.c index 2f9be9a3..bad519a1 100644 --- a/source/fitz/load-jpx.c +++ b/source/fitz/load-jpx.c @@ -818,7 +818,7 @@ jpx_read_image(fz_context *ctx, fz_jpxd *state, unsigned char *data, size_t size fz_try(ctx) { a = !!a; /* ignore any superfluous alpha channels */ - img = fz_new_pixmap(ctx, state->cs, w, h, a); + img = fz_new_pixmap(ctx, state->cs, w, h, NULL, a); p = img->samples; if (upsample_required) diff --git a/source/fitz/load-jxr.c b/source/fitz/load-jxr.c index f7a60f9f..d81196c2 100644 --- a/source/fitz/load-jxr.c +++ b/source/fitz/load-jxr.c @@ -400,7 +400,7 @@ fz_load_jxr(fz_context *ctx, unsigned char *data, size_t size) jxr_read_image(ctx, data, size, &info, 0); - image = fz_new_pixmap(ctx, info.cspace, info.width, info.height, 1); + image = fz_new_pixmap(ctx, info.cspace, info.width, info.height, NULL, 1); image->xres = info.xres; image->yres = info.yres; diff --git a/source/fitz/load-png.c b/source/fitz/load-png.c index a89701b4..b774672a 100644 --- a/source/fitz/load-png.c +++ b/source/fitz/load-png.c @@ -502,7 +502,7 @@ png_read_image(fz_context *ctx, struct info *info, unsigned char *p, size_t tota static fz_pixmap * png_expand_palette(fz_context *ctx, struct info *info, fz_pixmap *src) { - fz_pixmap *dst = fz_new_pixmap(ctx, fz_device_rgb(ctx), src->w, src->h, 1); + fz_pixmap *dst = fz_new_pixmap(ctx, fz_device_rgb(ctx), src->w, src->h, NULL, 1); unsigned char *sp = src->samples; unsigned char *dp = dst->samples; unsigned int x, y; @@ -574,7 +574,7 @@ fz_load_png(fz_context *ctx, unsigned char *p, size_t total) fz_try(ctx) { - image = fz_new_pixmap(ctx, colorspace, png.width, png.height, 1); + image = fz_new_pixmap(ctx, colorspace, png.width, png.height, NULL, 1); } fz_catch(ctx) { diff --git a/source/fitz/load-pnm.c b/source/fitz/load-pnm.c index d5d6b9c7..9e38dcbd 100644 --- a/source/fitz/load-pnm.c +++ b/source/fitz/load-pnm.c @@ -264,7 +264,7 @@ pnm_ascii_read_image(fz_context *ctx, struct info *pnm, unsigned char *p, unsign int x, y, k; int w, h, n; - img = fz_new_pixmap(ctx, pnm->cs, pnm->width, pnm->height, 0); + img = fz_new_pixmap(ctx, pnm->cs, pnm->width, pnm->height, NULL, 0); dp = img->samples; w = img->w; @@ -342,7 +342,7 @@ pnm_binary_read_image(fz_context *ctx, struct info *pnm, unsigned char *p, unsig int x, y, k; int w, h, n; - img = fz_new_pixmap(ctx, pnm->cs, pnm->width, pnm->height, 0); + img = fz_new_pixmap(ctx, pnm->cs, pnm->width, pnm->height, NULL, 0); dp = img->samples; w = img->w; @@ -506,7 +506,7 @@ pam_binary_read_image(fz_context *ctx, struct info *pnm, unsigned char *p, unsig int x, y, k, packed = 0; int w, h, n; - img = fz_new_pixmap(ctx, pnm->cs, pnm->width, pnm->height, pnm->alpha); + img = fz_new_pixmap(ctx, pnm->cs, pnm->width, pnm->height, NULL, pnm->alpha); fz_try(ctx) { dp = img->samples; diff --git a/source/fitz/load-tiff.c b/source/fitz/load-tiff.c index 881498c0..77539876 100644 --- a/source/fitz/load-tiff.c +++ b/source/fitz/load-tiff.c @@ -1313,7 +1313,7 @@ fz_load_tiff_subimage(fz_context *ctx, unsigned char *buf, size_t len, int subim /* Expand into fz_pixmap struct */ alpha = tiff.extrasamples != 0; - image = fz_new_pixmap(ctx, tiff.colorspace, tiff.imagewidth, tiff.imagelength, alpha); + image = fz_new_pixmap(ctx, tiff.colorspace, tiff.imagewidth, tiff.imagelength, NULL, alpha); image->xres = tiff.xresolution; image->yres = tiff.yresolution; diff --git a/source/fitz/pixmap.c b/source/fitz/pixmap.c index b568c842..2ac8bae5 100644 --- a/source/fitz/pixmap.c +++ b/source/fitz/pixmap.c @@ -23,21 +23,23 @@ fz_drop_pixmap_imp(fz_context *ctx, fz_storable *pix_) fz_pixmap *pix = (fz_pixmap *)pix_; fz_drop_colorspace(ctx, pix->colorspace); - if (pix->free_samples) + fz_drop_separations(ctx, pix->seps); + if (pix->flags & FZ_PIXMAP_FLAG_FREE_SAMPLES) fz_free(ctx, pix->samples); fz_free(ctx, pix); } fz_pixmap * -fz_new_pixmap_with_data(fz_context *ctx, fz_colorspace *colorspace, int w, int h, int alpha, int stride, unsigned char *samples) +fz_new_pixmap_with_data(fz_context *ctx, fz_colorspace *colorspace, int w, int h, fz_separations *seps, int alpha, int stride, unsigned char *samples) { fz_pixmap *pix; + int s = fz_count_active_separations(ctx, seps); int n; if (w < 0 || h < 0) fz_throw(ctx, FZ_ERROR_GENERIC, "Illegal dimensions for pixmap %d %d", w, h); - n = alpha + fz_colorspace_n(ctx, colorspace); + n = alpha + s + fz_colorspace_n(ctx, colorspace); if (stride < n*w && stride > -n*w) fz_throw(ctx, FZ_ERROR_GENERIC, "Illegal stride for pixmap (n=%d w=%d, stride=%d)", n, w, stride); if (samples == NULL && stride < n*w) @@ -50,11 +52,13 @@ fz_new_pixmap_with_data(fz_context *ctx, fz_colorspace *colorspace, int w, int h pix->w = w; pix->h = h; pix->alpha = alpha = !!alpha; - pix->interpolate = 1; + pix->flags = FZ_PIXMAP_FLAG_INTERPOLATE; pix->xres = 96; pix->yres = 96; pix->colorspace = NULL; pix->n = n; + pix->s = s; + pix->seps = fz_keep_separations(ctx, seps); pix->stride = stride; if (colorspace) @@ -63,15 +67,11 @@ fz_new_pixmap_with_data(fz_context *ctx, fz_colorspace *colorspace, int w, int h } else { - assert(alpha); + assert(alpha || s); } pix->samples = samples; - if (samples) - { - pix->free_samples = 0; - } - else + if (!samples) { fz_try(ctx) { @@ -85,40 +85,42 @@ fz_new_pixmap_with_data(fz_context *ctx, fz_colorspace *colorspace, int w, int h fz_free(ctx, pix); fz_rethrow(ctx); } - pix->free_samples = 1; + pix->flags |= FZ_PIXMAP_FLAG_FREE_SAMPLES; } return pix; } fz_pixmap * -fz_new_pixmap(fz_context *ctx, fz_colorspace *colorspace, int w, int h, int alpha) +fz_new_pixmap(fz_context *ctx, fz_colorspace *colorspace, int w, int h, fz_separations *seps, int alpha) { int stride; - if (!colorspace) alpha = 1; - stride = (fz_colorspace_n(ctx, colorspace) + alpha) * w; - return fz_new_pixmap_with_data(ctx, colorspace, w, h, alpha, stride, NULL); + int s = fz_count_active_separations(ctx, seps); + if (!colorspace && s == 0) alpha = 1; + stride = (fz_colorspace_n(ctx, colorspace) + s + alpha) * w; + return fz_new_pixmap_with_data(ctx, colorspace, w, h, seps, alpha, stride, NULL); } fz_pixmap * -fz_new_pixmap_with_bbox(fz_context *ctx, fz_colorspace *colorspace, const fz_irect *r, int alpha) +fz_new_pixmap_with_bbox(fz_context *ctx, fz_colorspace *colorspace, const fz_irect *r, fz_separations *seps, int alpha) { fz_pixmap *pixmap; - pixmap = fz_new_pixmap(ctx, colorspace, r->x1 - r->x0, r->y1 - r->y0, alpha); + pixmap = fz_new_pixmap(ctx, colorspace, r->x1 - r->x0, r->y1 - r->y0, seps, alpha); pixmap->x = r->x0; pixmap->y = r->y0; return pixmap; } fz_pixmap * -fz_new_pixmap_with_bbox_and_data(fz_context *ctx, fz_colorspace *colorspace, const fz_irect *r, int alpha, unsigned char *samples) +fz_new_pixmap_with_bbox_and_data(fz_context *ctx, fz_colorspace *colorspace, const fz_irect *r, fz_separations *seps, int alpha, unsigned char *samples) { int w = r->x1 - r->x0; int stride; + int s = fz_count_active_separations(ctx, seps); fz_pixmap *pixmap; - if (!colorspace) alpha = 1; - stride = (fz_colorspace_n(ctx, colorspace) + alpha) * w; - pixmap = fz_new_pixmap_with_data(ctx, colorspace, w, r->y1 - r->y0, alpha, stride, samples); + if (!colorspace && s == 0) alpha = 1; + stride = (fz_colorspace_n(ctx, colorspace) + s + alpha) * w; + pixmap = fz_new_pixmap_with_data(ctx, colorspace, w, r->y1 - r->y0, seps, alpha, stride, samples); pixmap->x = r->x0; pixmap->y = r->y0; return pixmap; @@ -185,7 +187,19 @@ fz_pixmap_components(fz_context *ctx, fz_pixmap *pix) int fz_pixmap_colorants(fz_context *ctx, fz_pixmap *pix) { - return pix->n - pix->alpha; + return pix->n - pix->alpha - pix->s; +} + +int +fz_pixmap_spots(fz_context *ctx, fz_pixmap *pix) +{ + return pix->s; +} + +int +fz_pixmap_alpha(fz_context *ctx, fz_pixmap *pix) +{ + return pix->alpha; } int @@ -661,7 +675,7 @@ fz_alpha_from_gray(fz_context *ctx, fz_pixmap *gray) assert(gray->n == 1); - alpha = fz_new_pixmap_with_bbox(ctx, NULL, fz_pixmap_bbox(ctx, gray, &bbox), 1); + alpha = fz_new_pixmap_with_bbox(ctx, NULL, fz_pixmap_bbox(ctx, gray, &bbox), 0, 1); dp = alpha->samples; dstride = alpha->stride; sp = gray->samples; @@ -813,13 +827,16 @@ fz_convert_pixmap(fz_context *ctx, fz_pixmap *pix, fz_colorspace *ds, fz_colorsp if (color_params == NULL) color_params = fz_default_color_params(ctx); - cvt = fz_new_pixmap(ctx, ds, pix->w, pix->h, keep_alpha && pix->alpha); + cvt = fz_new_pixmap(ctx, ds, pix->w, pix->h, pix->seps, keep_alpha && pix->alpha); cvt->xres = pix->xres; cvt->yres = pix->yres; cvt->x = pix->x; cvt->y = pix->y; - cvt->interpolate = pix->interpolate; + if (pix->flags & FZ_PIXMAP_FLAG_INTERPOLATE) + cvt->flags |= FZ_PIXMAP_FLAG_INTERPOLATE; + else + cvt->flags &= ~FZ_PIXMAP_FLAG_INTERPOLATE; fz_try(ctx) { @@ -838,7 +855,7 @@ fz_convert_pixmap(fz_context *ctx, fz_pixmap *pix, fz_colorspace *ds, fz_colorsp fz_pixmap * fz_new_pixmap_from_8bpp_data(fz_context *ctx, int x, int y, int w, int h, unsigned char *sp, int span) { - fz_pixmap *pixmap = fz_new_pixmap(ctx, NULL, w, h, 1); + fz_pixmap *pixmap = fz_new_pixmap(ctx, NULL, w, h, NULL, 1); int stride = pixmap->stride; unsigned char *s = pixmap->samples; pixmap->x = x; @@ -856,7 +873,7 @@ fz_new_pixmap_from_8bpp_data(fz_context *ctx, int x, int y, int w, int h, unsign fz_pixmap * fz_new_pixmap_from_1bpp_data(fz_context *ctx, int x, int y, int w, int h, unsigned char *sp, int span) { - fz_pixmap *pixmap = fz_new_pixmap(ctx, NULL, w, h, 1); + fz_pixmap *pixmap = fz_new_pixmap(ctx, NULL, w, h, NULL, 1); int stride = pixmap->stride - pixmap->w; pixmap->x = x; pixmap->y = y; diff --git a/source/fitz/separation.c b/source/fitz/separation.c index 039223a9..45b60b92 100644 --- a/source/fitz/separation.c +++ b/source/fitz/separation.c @@ -1,11 +1,17 @@ #include "mupdf/fitz.h" +enum +{ + FZ_SEPARATION_DISABLED_RENDER = 3 +}; + + struct fz_separations_s { int refs; int num_separations; int controllable; - uint32_t disabled[(FZ_MAX_SEPARATIONS + 31) / 32]; + uint32_t state[(2*FZ_MAX_SEPARATIONS + 31) / 32]; uint32_t equiv_rgb[FZ_MAX_SEPARATIONS]; uint32_t equiv_cmyk[FZ_MAX_SEPARATIONS]; char *name[FZ_MAX_SEPARATIONS]; @@ -56,59 +62,65 @@ void fz_add_separation(fz_context *ctx, fz_separations *sep, uint32_t rgb, uint3 sep->num_separations++; } -int fz_separations_controllable(fz_context *ctx, fz_separations *sep) +int fz_separations_controllable(fz_context *ctx, const fz_separations *sep) { return (!sep || sep->controllable); } -void fz_control_separation(fz_context *ctx, fz_separations *sep, int separation, int disable) +void fz_set_separation_behavior(fz_context *ctx, fz_separations *sep, int separation, fz_separation_behavior beh) { - int bit; + int shift; + fz_separation_behavior old; if (!sep || separation < 0 || separation >= sep->num_separations) fz_throw(ctx, FZ_ERROR_GENERIC, "can't control non-existent separation"); - if (!sep->controllable) - fz_throw(ctx, FZ_ERROR_GENERIC, "can't control separations on this page"); + if (beh == FZ_SEPARATION_DISABLED && !sep->controllable) + beh = FZ_SEPARATION_DISABLED_RENDER; - bit = 1<<(separation & 31); - separation >>= 5; + shift = ((2*separation) & 31); + separation >>= 4; - if (disable) - { - /* If it's already disabled, great */ - if (sep->disabled[separation] & bit) - return; + old = (sep->state[separation]>>shift) & 3; - sep->disabled[separation] |= bit; - } - else - { - /* If it's already enabled, great */ - if ((sep->disabled[separation] & bit) == 0) - return; + if (old == (fz_separation_behavior)FZ_SEPARATION_DISABLED_RENDER) + old = FZ_SEPARATION_DISABLED; + + /* If no change, great */ + if (old == beh) + return; + + sep->state[separation] = (sep->state[separation] & ~(3<<shift)) | (beh<<shift); - sep->disabled[separation] &= ~bit; - } /* FIXME: Could only empty images from the store, or maybe only * images that depend on separations. */ fz_empty_store(ctx); } -int fz_separation_disabled(fz_context *ctx, fz_separations *sep, int separation) +static inline fz_separation_behavior +sep_state(const fz_separations *sep, int i) { - int bit; + return (fz_separation_behavior)((sep->state[i>>5]>>((2*i) & 31)) & 3); +} +fz_separation_behavior fz_separation_current_behavior_internal(fz_context *ctx, const fz_separations *sep, int separation) +{ if (!sep || separation < 0 || separation >= sep->num_separations) fz_throw(ctx, FZ_ERROR_GENERIC, "can't disable non-existent separation"); - bit = 1<<(separation & 31); - separation >>= 5; + return sep_state(sep, separation); +} + +fz_separation_behavior fz_separation_current_behavior(fz_context *ctx, const fz_separations *sep, int separation) +{ + int beh = fz_separation_current_behavior_internal(ctx, sep, separation); - return ((sep->disabled[separation] & bit) != 0); + if (beh == FZ_SEPARATION_DISABLED_RENDER) + return FZ_SEPARATION_DISABLED; + return beh; } -int fz_separations_all_enabled(fz_context *ctx, fz_separations *sep) +int fz_separations_all_composite(fz_context *ctx, const fz_separations *sep) { int i; @@ -116,13 +128,13 @@ int fz_separations_all_enabled(fz_context *ctx, fz_separations *sep) return 1; for (i = 0; i < (FZ_MAX_SEPARATIONS + 31) / 32; i++) - if (sep->disabled[i] != 0) + if (sep->state[i] != FZ_SEPARATION_COMPOSITE) return 0; return 1; } -const char *fz_get_separation(fz_context *ctx, fz_separations *sep, int separation, uint32_t *rgb, uint32_t *cmyk) +const char *fz_get_separation(fz_context *ctx, const fz_separations *sep, int separation, uint32_t *rgb, uint32_t *cmyk) { if (!sep || separation < 0 || separation >= sep->num_separations) fz_throw(ctx, FZ_ERROR_GENERIC, "can't access non-existent separation"); @@ -135,9 +147,23 @@ const char *fz_get_separation(fz_context *ctx, fz_separations *sep, int separati return sep->name[separation]; } -int fz_count_separations(fz_context *ctx, fz_separations *sep) +int fz_count_separations(fz_context *ctx, const fz_separations *sep) { if (!sep) return 0; return sep->num_separations; } + +int fz_count_active_separations(fz_context *ctx, const fz_separations *sep) +{ + int i, n, c; + + if (!sep) + return 0; + n = sep->num_separations; + c = 0; + for (i = 0; i < n; i++) + if (sep_state(sep, i) == FZ_SEPARATION_SPOT) + c++; + return c; +} diff --git a/source/fitz/svg-device.c b/source/fitz/svg-device.c index b327824f..036c8563 100644 --- a/source/fitz/svg-device.c +++ b/source/fitz/svg-device.c @@ -980,7 +980,7 @@ svg_dev_fill_shade(fz_context *ctx, fz_device *dev, fz_shade *shade, const fz_ma fz_round_rect(&bbox, fz_intersect_rect(fz_bound_shade(ctx, shade, ctm, &rect), &dev->container[dev->container_len-1].scissor)); if (fz_is_empty_irect(&bbox)) return; - pix = fz_new_pixmap_with_bbox(ctx, fz_device_rgb(ctx), &bbox, 1); + pix = fz_new_pixmap_with_bbox(ctx, fz_device_rgb(ctx), &bbox, NULL, 1); fz_clear_pixmap(ctx, pix); fz_try(ctx) diff --git a/source/fitz/util.c b/source/fitz/util.c index 23dab179..f4dee8a1 100644 --- a/source/fitz/util.c +++ b/source/fitz/util.c @@ -114,7 +114,7 @@ fz_new_pixmap_from_display_list(fz_context *ctx, fz_display_list *list, const fz fz_transform_rect(&rect, ctm); fz_round_rect(&irect, &rect); - pix = fz_new_pixmap_with_bbox(ctx, cs, &irect, alpha); + pix = fz_new_pixmap_with_bbox(ctx, cs, &irect, 0, alpha); if (alpha) fz_clear_pixmap(ctx, pix); else @@ -151,7 +151,7 @@ fz_new_pixmap_from_page_contents(fz_context *ctx, fz_page *page, const fz_matrix fz_transform_rect(&rect, ctm); fz_round_rect(&irect, &rect); - pix = fz_new_pixmap_with_bbox(ctx, cs, &irect, alpha); + pix = fz_new_pixmap_with_bbox(ctx, cs, &irect, 0, alpha); if (alpha) fz_clear_pixmap(ctx, pix); else @@ -188,7 +188,7 @@ fz_new_pixmap_from_annot(fz_context *ctx, fz_annot *annot, const fz_matrix *ctm, fz_transform_rect(&rect, ctm); fz_round_rect(&irect, &rect); - pix = fz_new_pixmap_with_bbox(ctx, cs, &irect, alpha); + pix = fz_new_pixmap_with_bbox(ctx, cs, &irect, 0, alpha); if (alpha) fz_clear_pixmap(ctx, pix); else @@ -225,7 +225,7 @@ fz_new_pixmap_from_page(fz_context *ctx, fz_page *page, const fz_matrix *ctm, fz fz_transform_rect(&rect, ctm); fz_round_rect(&irect, &rect); - pix = fz_new_pixmap_with_bbox(ctx, cs, &irect, alpha); + pix = fz_new_pixmap_with_bbox(ctx, cs, &irect, 0, alpha); if (alpha) fz_clear_pixmap(ctx, pix); else diff --git a/source/gprf/gprf-doc.c b/source/gprf/gprf-doc.c index a7c46524..74b50a9b 100644 --- a/source/gprf/gprf-doc.c +++ b/source/gprf/gprf-doc.c @@ -329,7 +329,7 @@ gprf_get_pixmap(fz_context *ctx, fz_image *image_, fz_irect *area, int w, int h, /* The file contains RGB + up to FZ_MAX_SEPARATIONS. Hence the * "3 + FZ_MAX_SEPARATIONS" usage in all the arrays below. */ fz_image_gprf *image = (fz_image_gprf *)image_; - fz_pixmap *pix = fz_new_pixmap(ctx, image->super.colorspace, image->super.w, image->super.h, 1); + fz_pixmap *pix = fz_new_pixmap(ctx, image->super.colorspace, image->super.w, image->super.h, NULL, 1); fz_stream *file[3 + FZ_MAX_SEPARATIONS] = { NULL }; int read_sep[3 + FZ_MAX_SEPARATIONS] = { 0 }; int num_seps, i, j, n; @@ -365,7 +365,7 @@ gprf_get_pixmap(fz_context *ctx, fz_image *image_, fz_irect *area, int w, int h, { for (i = 3; i < num_seps; i++) { - read_sep[i] = !fz_separation_disabled(ctx, image->separations, i-3); + read_sep[i] = !FZ_SEPARATION_DISABLED(ctx, image->separations, i-3); if (read_sep[i]) { uint32_t rgb, cmyk; @@ -851,7 +851,7 @@ static int gprf_separation_disabled(fz_context *ctx, fz_page *page_, int sep) { gprf_page *page = (gprf_page *)page_; - return fz_separation_disabled(ctx, page->separations, sep); + return FZ_SEPARATION_DISABLED(ctx, page->separations, sep); } static const char *gprf_get_separation(fz_context *ctx, fz_page *page_, int sep, uint32_t *rgba, uint32_t*cmyk) diff --git a/source/helpers/mu-office-lib/mu-office-lib.c b/source/helpers/mu-office-lib/mu-office-lib.c index 3e56369a..dc5be7e4 100644 --- a/source/helpers/mu-office-lib/mu-office-lib.c +++ b/source/helpers/mu-office-lib/mu-office-lib.c @@ -1001,6 +1001,7 @@ static void render_worker(void *arg) fz_device_rgb(ctx), render->area.renderArea.width, render->area.renderArea.height, + NULL, 1, render->bitmap->lineSkip, ((unsigned char *)render->bitmap->memptr) + diff --git a/source/tests/mu-office-test.c b/source/tests/mu-office-test.c index aef50981..d729de88 100644 --- a/source/tests/mu-office-test.c +++ b/source/tests/mu-office-test.c @@ -269,7 +269,7 @@ save_png(const MuOfficeBitmap *bitmap, const char *filename) fz_try(ctx) { - pix = fz_new_pixmap_with_data(ctx, fz_device_rgb(ctx), bitmap->width, bitmap->height, 1, bitmap->lineSkip, bitmap->memptr); + pix = fz_new_pixmap_with_data(ctx, fz_device_rgb(ctx), bitmap->width, bitmap->height, NULL, 1, bitmap->lineSkip, bitmap->memptr); fz_save_pixmap_as_png(ctx, pix, filename); } diff --git a/source/tools/mudraw.c b/source/tools/mudraw.c index 1579e905..1959dddc 100644 --- a/source/tools/mudraw.c +++ b/source/tools/mudraw.c @@ -774,7 +774,7 @@ static void dodrawpage(fz_context *ctx, fz_page *page, fz_display_list *list, in workers[band].tbounds = tbounds; memset(&workers[band].cookie, 0, sizeof(fz_cookie)); workers[band].list = list; - workers[band].pix = fz_new_pixmap_with_bbox(ctx, colorspace, &band_ibounds, alpha); + workers[band].pix = fz_new_pixmap_with_bbox(ctx, colorspace, &band_ibounds, NULL, alpha); fz_set_pixmap_resolution(ctx, workers[band].pix, resolution, resolution); #ifndef DISABLE_MUTHREADS DEBUG_THREADS(("Worker %d, Pre-triggering band %d\n", band, band)); @@ -786,7 +786,7 @@ static void dodrawpage(fz_context *ctx, fz_page *page, fz_display_list *list, in } else { - pix = fz_new_pixmap_with_bbox(ctx, colorspace, &band_ibounds, alpha); + pix = fz_new_pixmap_with_bbox(ctx, colorspace, &band_ibounds, NULL, alpha); fz_set_pixmap_resolution(ctx, pix, resolution, resolution); } diff --git a/source/tools/muraster.c b/source/tools/muraster.c index 77d60b8f..cbc8be27 100644 --- a/source/tools/muraster.c +++ b/source/tools/muraster.c @@ -601,7 +601,7 @@ static int dodrawpage(fz_context *ctx, int pagenum, fz_cookie *cookie, render_de if (remaining_height < band_height) ibounds.y1 = ibounds.y0 + remaining_height; remaining_height -= band_height; - w->pix = fz_new_pixmap_with_bbox(ctx, colorspace, &ibounds, 0); + w->pix = fz_new_pixmap_with_bbox(ctx, colorspace, &ibounds, NULL, 0); fz_set_pixmap_resolution(ctx, w->pix, x_resolution, y_resolution); DEBUG_THREADS(("Worker %d, Pre-triggering band %d\n", band, band)); w->started = 1; @@ -612,7 +612,7 @@ static int dodrawpage(fz_context *ctx, int pagenum, fz_cookie *cookie, render_de } else { - pix = fz_new_pixmap_with_bbox(ctx, colorspace, &ibounds, 0); + pix = fz_new_pixmap_with_bbox(ctx, colorspace, &ibounds, NULL, 0); fz_set_pixmap_resolution(ctx, pix, x_resolution, y_resolution); } fz_write_header(ctx, render->bander, pix->w, total_height, pix->n, pix->alpha, pix->xres, pix->yres, pagenum, pix->colorspace); diff --git a/source/tools/murun.c b/source/tools/murun.c index ec9a93e3..cd000632 100644 --- a/source/tools/murun.c +++ b/source/tools/murun.c @@ -2024,7 +2024,7 @@ static void ffi_new_Pixmap(js_State *J) fz_pixmap *pixmap; fz_try(ctx) - pixmap = fz_new_pixmap_with_bbox(ctx, colorspace, &bounds, alpha); + pixmap = fz_new_pixmap_with_bbox(ctx, colorspace, &bounds, 0, alpha); fz_catch(ctx) rethrow(J); |