summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin Watts <robin.watts@artifex.com>2017-07-12 21:18:45 +0100
committerRobin Watts <robin.watts@artifex.com>2017-07-19 19:41:23 +0100
commitd54763bcd644364c19d3a6a12f889127df583e01 (patch)
tree379843a30fbb263e811ac6cbe3d2a4abe13b6fb3
parentd541fc4b9eced1b788377df8c7edfd9b8dea4094 (diff)
downloadmupdf-d54763bcd644364c19d3a6a12f889127df583e01.tar.xz
Update band writer (especially PSD) to cope with spots
PSD writer now outputs spot colors. Ensure subtractive colorspaces are stored with proper polarity. The CMYK and spot components need to be 255-X in the PSD format Store PSD format resources using correct Pascal style strings. Photoshop will fail to open if the the ICC profile resource name is not in proper format. (Incorporates fixes from Michael).
-rw-r--r--include/mupdf/fitz/band-writer.h6
-rw-r--r--source/fitz/bitmap.c10
-rw-r--r--source/fitz/output-pcl.c9
-rw-r--r--source/fitz/output-png.c7
-rw-r--r--source/fitz/output-pnm.c14
-rw-r--r--source/fitz/output-ps.c5
-rw-r--r--source/fitz/output-psd.c130
-rw-r--r--source/fitz/output-pwg.c6
-rw-r--r--source/fitz/output-tga.c4
-rw-r--r--source/fitz/output.c6
-rw-r--r--source/tools/mudraw.c2
-rw-r--r--source/tools/muraster.c4
12 files changed, 172 insertions, 31 deletions
diff --git a/include/mupdf/fitz/band-writer.h b/include/mupdf/fitz/band-writer.h
index 95385d5f..e32d5185 100644
--- a/include/mupdf/fitz/band-writer.h
+++ b/include/mupdf/fitz/band-writer.h
@@ -25,11 +25,13 @@ struct fz_band_writer_s
int w;
int h;
int n;
+ int s;
int alpha;
int xres;
int yres;
int pagenum;
int line;
+ fz_separations *seps;
};
fz_band_writer *fz_new_band_writer_of_size(fz_context *ctx, size_t size, fz_output *out);
@@ -53,9 +55,11 @@ fz_band_writer *fz_new_band_writer_of_size(fz_context *ctx, size_t size, fz_outp
cs: Colorspace (NULL for bitmaps)
+ seps: Separation details (or NULL).
+
Throws exception if incompatible data format.
*/
-void fz_write_header(fz_context *ctx, fz_band_writer *writer, int w, int h, int n, int alpha, int xres, int yres, int pagenum, const fz_colorspace *cs);
+void fz_write_header(fz_context *ctx, fz_band_writer *writer, int w, int h, int n, int alpha, int xres, int yres, int pagenum, const fz_colorspace *cs, fz_separations *seps);
/*
fz_write_band: Cause a band writer to write the next band
diff --git a/source/fitz/bitmap.c b/source/fitz/bitmap.c
index 37aabe7b..cee3a3fa 100644
--- a/source/fitz/bitmap.c
+++ b/source/fitz/bitmap.c
@@ -312,6 +312,9 @@ pbm_write_header(fz_context *ctx, fz_band_writer *writer, const fz_colorspace *c
int w = writer->w;
int h = writer->h;
+ if (writer->s != 0)
+ fz_throw(ctx, FZ_ERROR_GENERIC, "pbms cannot contain spot colors");
+
fz_write_printf(ctx, out, "P4\n%d %d\n", w, h);
}
@@ -322,6 +325,9 @@ pkm_write_header(fz_context *ctx, fz_band_writer *writer, const fz_colorspace *c
int w = writer->w;
int h = writer->h;
+ if (writer->s != 0)
+ fz_throw(ctx, FZ_ERROR_GENERIC, "pkms cannot contain spot colors");
+
fz_write_printf(ctx, out, "P7\nWIDTH %d\nHEIGHT %d\nDEPTH 4\nMAXVAL 255\nTUPLTYPE CMYK\nENDHDR\n", w, h);
}
@@ -336,7 +342,7 @@ fz_write_bitmap_as_pbm(fz_context *ctx, fz_output *out, fz_bitmap *bitmap)
writer = fz_new_pbm_band_writer(ctx, out);
fz_try(ctx)
{
- fz_write_header(ctx, writer, bitmap->w, bitmap->h, 1, 0, 0, 0, 0, NULL);
+ fz_write_header(ctx, writer, bitmap->w, bitmap->h, 1, 0, 0, 0, 0, NULL, NULL);
fz_write_band(ctx, writer, bitmap->stride, bitmap->h, bitmap->samples);
}
fz_always(ctx)
@@ -356,7 +362,7 @@ fz_write_bitmap_as_pkm(fz_context *ctx, fz_output *out, fz_bitmap *bitmap)
writer = fz_new_pkm_band_writer(ctx, out);
fz_try(ctx)
{
- fz_write_header(ctx, writer, bitmap->w, bitmap->h, 4, 0, 0, 0, 0, NULL);
+ fz_write_header(ctx, writer, bitmap->w, bitmap->h, 4, 0, 0, 0, 0, NULL, NULL);
fz_write_band(ctx, writer, bitmap->stride, bitmap->h, bitmap->samples);
}
fz_always(ctx)
diff --git a/source/fitz/output-pcl.c b/source/fitz/output-pcl.c
index 7f676cf5..bb3a82dd 100644
--- a/source/fitz/output-pcl.c
+++ b/source/fitz/output-pcl.c
@@ -691,7 +691,7 @@ fz_write_pixmap_as_pcl(fz_context *ctx, fz_output *out, const fz_pixmap *pixmap,
writer = fz_new_color_pcl_band_writer(ctx, out, pcl);
fz_try(ctx)
{
- fz_write_header(ctx, writer, pixmap->w, pixmap->h, pixmap->n, pixmap->alpha, pixmap->xres, pixmap->yres, 0, pixmap->colorspace);
+ fz_write_header(ctx, writer, pixmap->w, pixmap->h, pixmap->n, pixmap->alpha, pixmap->xres, pixmap->yres, 0, pixmap->colorspace, pixmap->seps);
fz_write_band(ctx, writer, pixmap->stride, pixmap->h, pixmap->samples);
}
fz_always(ctx)
@@ -723,7 +723,7 @@ color_pcl_write_header(fz_context *ctx, fz_band_writer *writer_, const fz_colors
int xres = writer->super.xres;
int yres = writer->super.yres;
- if (n != 4)
+ if (n != 4 || writer->super.s != 0)
fz_throw(ctx, FZ_ERROR_GENERIC, "pixmap must be rgb to write as pcl");
writer->linebuf = fz_malloc(ctx, w * 3 * 2);
@@ -1078,7 +1078,7 @@ fz_write_bitmap_as_pcl(fz_context *ctx, fz_output *out, const fz_bitmap *bitmap,
writer = fz_new_mono_pcl_band_writer(ctx, out, pcl);
fz_try(ctx)
{
- fz_write_header(ctx, writer, bitmap->w, bitmap->h, 1, 0, bitmap->xres, bitmap->yres, 0, NULL);
+ fz_write_header(ctx, writer, bitmap->w, bitmap->h, 1, 0, bitmap->xres, bitmap->yres, 0, NULL, NULL);
fz_write_band(ctx, writer, bitmap->stride, bitmap->h, bitmap->samples);
}
fz_always(ctx)
@@ -1111,6 +1111,9 @@ mono_pcl_write_header(fz_context *ctx, fz_band_writer *writer_, const fz_colorsp
int max_mode_2_size;
int max_mode_3_size;
+ if (writer->super.s != 0)
+ fz_throw(ctx, FZ_ERROR_GENERIC, "Mono PCL cannot write spot colors");
+
line_size = (w + 7)/8;
max_mode_2_size = line_size + (line_size/127) + 1;
max_mode_3_size = line_size + (line_size/8) + 1;
diff --git a/source/fitz/output-png.c b/source/fitz/output-png.c
index e86c82c9..b86ea648 100644
--- a/source/fitz/output-png.c
+++ b/source/fitz/output-png.c
@@ -33,7 +33,7 @@ fz_save_pixmap_as_png(fz_context *ctx, fz_pixmap *pixmap, const char *filename)
fz_try(ctx)
{
writer = fz_new_png_band_writer(ctx, out);
- fz_write_header(ctx, writer, pixmap->w, pixmap->h, pixmap->n, pixmap->alpha, pixmap->xres, pixmap->yres, 0, pixmap->colorspace);
+ fz_write_header(ctx, writer, pixmap->w, pixmap->h, pixmap->n, pixmap->alpha, pixmap->xres, pixmap->yres, 0, pixmap->colorspace, pixmap->seps);
fz_write_band(ctx, writer, pixmap->stride, pixmap->h, pixmap->samples);
}
fz_always(ctx)
@@ -59,7 +59,7 @@ fz_write_pixmap_as_png(fz_context *ctx, fz_output *out, const fz_pixmap *pixmap)
fz_try(ctx)
{
- fz_write_header(ctx, writer, pixmap->w, pixmap->h, pixmap->n, pixmap->alpha, pixmap->xres, pixmap->yres, 0, pixmap->colorspace);
+ fz_write_header(ctx, writer, pixmap->w, pixmap->h, pixmap->n, pixmap->alpha, pixmap->xres, pixmap->yres, 0, pixmap->colorspace, pixmap->seps);
fz_write_band(ctx, writer, pixmap->stride, pixmap->h, pixmap->samples);
}
fz_always(ctx)
@@ -147,6 +147,9 @@ png_write_header(fz_context *ctx, fz_band_writer *writer_, const fz_colorspace *
unsigned char head[13];
int color;
+ if (writer->super.s != 0)
+ fz_throw(ctx, FZ_ERROR_GENERIC, "PNGs cannot contain spot colors");
+
/* Treat alpha only as greyscale */
if (n == 1 && alpha)
alpha = 0;
diff --git a/source/fitz/output-pnm.c b/source/fitz/output-pnm.c
index 2b39899e..2c4d4d30 100644
--- a/source/fitz/output-pnm.c
+++ b/source/fitz/output-pnm.c
@@ -12,6 +12,9 @@ pnm_write_header(fz_context *ctx, fz_band_writer *writer, const fz_colorspace *c
int n = writer->n;
int alpha = writer->alpha;
+ if (writer->s != 0)
+ fz_throw(ctx, FZ_ERROR_GENERIC, "PNM writer cannot cope with spot colors");
+
n -= alpha;
if (n != 1 && n != 3)
fz_throw(ctx, FZ_ERROR_GENERIC, "pixmap must be grayscale or rgb to write as pnm");
@@ -125,7 +128,7 @@ fz_write_pixmap_as_pnm(fz_context *ctx, fz_output *out, fz_pixmap *pixmap)
fz_band_writer *writer = fz_new_pnm_band_writer(ctx, out);
fz_try(ctx)
{
- fz_write_header(ctx, writer, pixmap->w, pixmap->h, pixmap->n, pixmap->alpha, 0, 0, 0, pixmap->colorspace);
+ fz_write_header(ctx, writer, pixmap->w, pixmap->h, pixmap->n, pixmap->alpha, 0, 0, 0, pixmap->colorspace, pixmap->seps);
fz_write_band(ctx, writer, pixmap->stride, pixmap->h, pixmap->samples);
}
fz_always(ctx)
@@ -145,7 +148,7 @@ fz_save_pixmap_as_pnm(fz_context *ctx, fz_pixmap *pixmap, const char *filename)
fz_try(ctx)
{
writer = fz_new_pnm_band_writer(ctx, out);
- fz_write_header(ctx, writer, pixmap->w, pixmap->h, pixmap->n, pixmap->alpha, 0, 0, 0, pixmap->colorspace);
+ fz_write_header(ctx, writer, pixmap->w, pixmap->h, pixmap->n, pixmap->alpha, 0, 0, 0, pixmap->colorspace, pixmap->seps);
fz_write_band(ctx, writer, pixmap->stride, pixmap->h, pixmap->samples);
}
fz_always(ctx)
@@ -170,6 +173,9 @@ pam_write_header(fz_context *ctx, fz_band_writer *writer, const fz_colorspace *c
int n = writer->n;
int alpha = writer->alpha;
+ if (writer->s != 0)
+ fz_throw(ctx, FZ_ERROR_GENERIC, "PAM writer cannot cope with spot colors");
+
fz_write_printf(ctx, out, "P7\n");
fz_write_printf(ctx, out, "WIDTH %d\n", w);
fz_write_printf(ctx, out, "HEIGHT %d\n", h);
@@ -228,7 +234,7 @@ fz_write_pixmap_as_pam(fz_context *ctx, fz_output *out, fz_pixmap *pixmap)
fz_band_writer *writer = fz_new_pam_band_writer(ctx, out);
fz_try(ctx)
{
- fz_write_header(ctx, writer, pixmap->w, pixmap->h, pixmap->n, pixmap->alpha, 0, 0, 0, pixmap->colorspace);
+ fz_write_header(ctx, writer, pixmap->w, pixmap->h, pixmap->n, pixmap->alpha, 0, 0, 0, pixmap->colorspace, pixmap->seps);
fz_write_band(ctx, writer, pixmap->stride, pixmap->h, pixmap->samples);
}
fz_always(ctx)
@@ -248,7 +254,7 @@ fz_save_pixmap_as_pam(fz_context *ctx, fz_pixmap *pixmap, const char *filename)
fz_try(ctx)
{
writer = fz_new_pam_band_writer(ctx, out);
- fz_write_header(ctx, writer, pixmap->w, pixmap->h, pixmap->n, pixmap->alpha, 0, 0, 0, pixmap->colorspace);
+ fz_write_header(ctx, writer, pixmap->w, pixmap->h, pixmap->n, pixmap->alpha, 0, 0, 0, pixmap->colorspace, pixmap->seps);
fz_write_band(ctx, writer, pixmap->stride, pixmap->h, pixmap->samples);
}
fz_always(ctx)
diff --git a/source/fitz/output-ps.c b/source/fitz/output-ps.c
index 126c54ff..3c8c3146 100644
--- a/source/fitz/output-ps.c
+++ b/source/fitz/output-ps.c
@@ -59,6 +59,9 @@ ps_write_header(fz_context *ctx, fz_band_writer *writer_, const fz_colorspace *c
float sy = (float) h / h_points;
int err;
+ if (writer->super.s != 0)
+ fz_throw(ctx, FZ_ERROR_GENERIC, "Postscript writer cannot cope with spot colors");
+
if (alpha != 0)
fz_throw(ctx, FZ_ERROR_GENERIC, "Postscript output cannot have alpha");
@@ -156,7 +159,7 @@ void fz_write_pixmap_as_ps(fz_context *ctx, fz_output *out, const fz_pixmap *pix
fz_try(ctx)
{
- fz_write_header(ctx, writer, pixmap->w, pixmap->h, pixmap->n, pixmap->alpha, pixmap->xres, pixmap->yres, 0, pixmap->colorspace);
+ fz_write_header(ctx, writer, pixmap->w, pixmap->h, pixmap->n, pixmap->alpha, pixmap->xres, pixmap->yres, 0, pixmap->colorspace, pixmap->seps);
fz_write_band(ctx, writer, pixmap->stride, pixmap->h, pixmap->samples);
}
fz_always(ctx)
diff --git a/source/fitz/output-psd.c b/source/fitz/output-psd.c
index 1c7adbc5..4d0f9574 100644
--- a/source/fitz/output-psd.c
+++ b/source/fitz/output-psd.c
@@ -11,7 +11,7 @@ fz_save_pixmap_as_psd(fz_context *ctx, fz_pixmap *pixmap, const char *filename)
fz_try(ctx)
{
writer = fz_new_psd_band_writer(ctx, out);
- fz_write_header(ctx, writer, pixmap->w, pixmap->h, pixmap->n, pixmap->alpha, pixmap->xres, pixmap->yres, 0, pixmap->colorspace);
+ fz_write_header(ctx, writer, pixmap->w, pixmap->h, pixmap->n, pixmap->alpha, pixmap->xres, pixmap->yres, 0, pixmap->colorspace, pixmap->seps);
fz_write_band(ctx, writer, pixmap->stride, pixmap->h, pixmap->samples);
}
fz_always(ctx)
@@ -37,7 +37,7 @@ fz_write_pixmap_as_psd(fz_context *ctx, fz_output *out, const fz_pixmap *pixmap)
fz_try(ctx)
{
- fz_write_header(ctx, writer, pixmap->w, pixmap->h, pixmap->n, pixmap->alpha, pixmap->xres, pixmap->yres, 0, pixmap->colorspace);
+ fz_write_header(ctx, writer, pixmap->w, pixmap->h, pixmap->n, pixmap->alpha, pixmap->xres, pixmap->yres, 0, pixmap->colorspace, pixmap->seps);
fz_write_band(ctx, writer, pixmap->stride, pixmap->h, pixmap->samples);
}
fz_always(ctx)
@@ -53,6 +53,7 @@ fz_write_pixmap_as_psd(fz_context *ctx, fz_output *out, const fz_pixmap *pixmap)
typedef struct psd_band_writer_s
{
fz_band_writer super;
+ int num_additive;
} psd_band_writer;
static void
@@ -62,21 +63,29 @@ psd_write_header(fz_context *ctx, fz_band_writer *writer_, const fz_colorspace *
fz_output *out = writer->super.out;
int w = writer->super.w;
int h = writer->super.h;
+ int s = writer->super.s;
int n = writer->super.n;
- int alpha = writer->super.alpha;
+ int c = n - writer->super.alpha - s;
+ fz_separations *seps = writer->super.seps;
+ int i;
+ size_t len;
static const char psdsig[12] = { '8', 'B', 'P', 'S', 0, 1, 0, 0, 0, 0, 0, 0 };
static const char ressig[4] = { '8', 'B', 'I', 'M' };
fz_buffer *buffer = fz_icc_data_from_icc_colorspace(ctx, cs);
unsigned char *data;
size_t size = fz_buffer_storage(ctx, buffer, &data);
+ if (!fz_colorspace_is_subtractive(ctx, cs))
+ writer->num_additive = fz_colorspace_n(ctx, cs);
+
/* File Header Section */
fz_write_data(ctx, out, psdsig, 12);
fz_write_int16_be(ctx, out, n);
fz_write_int32_be(ctx, out, h);
fz_write_int32_be(ctx, out, w);
fz_write_int16_be(ctx, out, 8); /* bits per channel */
- switch (n - alpha)
+
+ switch (c)
{
case 0:
case 1:
@@ -96,22 +105,105 @@ psd_write_header(fz_context *ctx, fz_band_writer *writer_, const fz_colorspace *
/* Color Mode Data Section - empty */
fz_write_int32_be(ctx, out, 0);
- /* Image Resources Section */
- if (size == 0)
- fz_write_int32_be(ctx, out, 0);
- else
+ /* Image Resources Section - Spot Names, Equivalent colors, resolution, ICC Profile */
+ /* Spot names */
+ len = 0;
+ for (i = 0; i < s; i++)
+ {
+ const char *name = fz_get_separation(ctx, seps, i, NULL, NULL);
+ char text[32];
+ size_t len2;
+ if (name == NULL)
+ {
+ sprintf(text, "Spot%d", i-4);
+ name = text;
+ }
+ len2 = strlen(name);
+ if (len2 > 255)
+ len2 = 255;
+ len += len2 + 1;
+ }
+
+ /* Write the size of all the following resources */
+ fz_write_int32_be(ctx, out,
+ (s ? 12 + ((len + 1)&~1) : 0) + /* Spot Names */
+ (s ? 12 + (14 * s) : 0) + /* DisplayInfo */
+ 28 + /* Resolutions */
+ (size ? (size+19)&~1 : 0)); /* ICC Profile */
+
+ /* Spot names */
+ if (s != 0)
+ {
+ fz_write_data(ctx, out, ressig, 4);
+ fz_write_int16_be(ctx, out , 0x03EE);
+ fz_write_int16_be(ctx, out, 0); /* PString */
+ fz_write_int32_be(ctx, out, (len + 1)&~1);
+ for (i = 0; i < s; i++) {
+ size_t len2;
+ const char *name = fz_get_separation(ctx, seps, i, NULL, NULL);
+ char text[32];
+ if (name == NULL)
+ {
+ sprintf(text, "Spot%d", i-4);
+ name = text;
+ }
+ len2 = strlen(name);
+ if (len2 > 255)
+ len2 = 255;
+ fz_write_byte(ctx, out, len2);
+ fz_write_data(ctx, out, name, len2);
+ }
+ if (len & 1)
+ {
+ fz_write_byte(ctx, out, 0);
+ }
+
+ /* DisplayInfo - Colors for each spot channel */
+ fz_write_data(ctx, out, ressig, 4);
+ fz_write_int16_be(ctx, out, 0x03EF);
+ fz_write_int16_be(ctx, out, 0); /* PString */
+ fz_write_int32_be(ctx, out, 14 * s); /* Length */
+ for (i = 0; i < s; i++) {
+ uint32_t cmyk;
+ (void)fz_get_separation(ctx, seps, i, NULL, &cmyk);
+ fz_write_int16_be(ctx, out, 02); /* CMYK */
+ /* PhotoShop stores all component values as if they were additive. */
+ fz_write_int16_be(ctx, out, 257 * (cmyk & 0xFF));/* Cyan */
+ fz_write_int16_be(ctx, out, 257 * ((cmyk>>8) & 0xFF));/* Magenta */
+ fz_write_int16_be(ctx, out, 257 * ((cmyk>>16) & 0xFF));/* Yellow */
+ fz_write_int16_be(ctx, out, 257 * ((cmyk>>24) & 0xFF));/* Black */
+ fz_write_int16_be(ctx, out, 0); /* Opacity 0 to 100 */
+ fz_write_byte(ctx, out, 2); /* Don't know */
+ fz_write_byte(ctx, out, 0); /* Padding - Always Zero */
+ }
+ }
+
+ /* ICC Profile - (size + 19)&~1 bytes */
+ if (size != 0)
{
- /* ICC Profile */
- fz_write_int32_be(ctx, out, 4+2+8+size+(size&1));
/* Image Resource block */
fz_write_data(ctx, out, ressig, 4);
fz_write_int16_be(ctx, out, 0x40f); /* ICC Profile */
- fz_write_data(ctx, out, "\0Profile", 8); /* Profile name (must be even!) */
+ fz_write_data(ctx, out, "\x07Profile", 8); /* Profile name (must be even!) */
+ fz_write_int32_be(ctx, out, size);
fz_write_data(ctx, out, data, size); /* Actual data */
if (size & 1)
fz_write_byte(ctx, out, 0); /* Pad to even */
}
+ /* Image resolution - 28 bytes */
+ fz_write_data(ctx, out, ressig, 4);
+ fz_write_int16_be(ctx, out, 0x03ED);
+ fz_write_int16_be(ctx, out, 0); /* PString */
+ fz_write_int32_be(ctx, out, 16); /* Length */
+ /* Resolution is specified as a fixed 16.16 bits */
+ fz_write_int32_be(ctx, out, writer->super.xres);
+ fz_write_int16_be(ctx, out, 1); /* width: 1 --> resolution is pixels per inch */
+ fz_write_int16_be(ctx, out, 1); /* width: 1 --> resolution is pixels per inch */
+ fz_write_int32_be(ctx, out, writer->super.yres);
+ fz_write_int16_be(ctx, out, 1); /* height: 1 --> resolution is pixels per inch */
+ fz_write_int16_be(ctx, out, 1); /* height: 1 --> resolution is pixels per inch */
+
/* Layer and Mask Information Section */
fz_write_int32_be(ctx, out, 0);
@@ -120,6 +212,15 @@ psd_write_header(fz_context *ctx, fz_band_writer *writer_, const fz_colorspace *
}
static void
+psd_invert_buffer(unsigned char *buffer, int size)
+{
+ int k;
+
+ for (k = 0; k < size; k++)
+ buffer[k] = 255 - buffer[k];
+}
+
+static void
psd_write_band(fz_context *ctx, fz_band_writer *writer_, int stride, int band_start, int band_height, const unsigned char *sp)
{
psd_band_writer *writer = (psd_band_writer *)(void *)writer_;
@@ -131,6 +232,7 @@ psd_write_band(fz_context *ctx, fz_band_writer *writer_, int stride, int band_st
unsigned char *b;
int plane_inc;
int line_skip;
+ int num_additive = writer->num_additive;
if (!out)
return;
@@ -156,6 +258,8 @@ psd_write_band(fz_context *ctx, fz_band_writer *writer_, int stride, int band_st
sp += n;
if (b == buffer_end)
{
+ if (k >= num_additive)
+ psd_invert_buffer(buffer, sizeof(buffer));
fz_write_data(ctx, out, buffer, sizeof(buffer));
b = buffer;
}
@@ -165,6 +269,8 @@ psd_write_band(fz_context *ctx, fz_band_writer *writer_, int stride, int band_st
sp -= stride * band_height - 1;
if (b != buffer)
{
+ if (k >= num_additive)
+ psd_invert_buffer(buffer, sizeof(buffer));
fz_write_data(ctx, out, buffer, b - buffer);
b = buffer;
}
@@ -200,5 +306,7 @@ fz_band_writer *fz_new_psd_band_writer(fz_context *ctx, fz_output *out)
writer->super.trailer = psd_write_trailer;
writer->super.drop = psd_drop_band_writer;
+ writer->num_additive = 0;
+
return &writer->super;
}
diff --git a/source/fitz/output-pwg.c b/source/fitz/output-pwg.c
index f36c3a2b..2cd79afe 100644
--- a/source/fitz/output-pwg.c
+++ b/source/fitz/output-pwg.c
@@ -102,7 +102,7 @@ fz_write_pixmap_as_pwg_page(fz_context *ctx, fz_output *out, const fz_pixmap *pi
fz_try(ctx)
{
- fz_write_header(ctx, writer, pixmap->w, pixmap->h, pixmap->n, pixmap->alpha, pixmap->xres, pixmap->yres, 0, pixmap->colorspace);
+ fz_write_header(ctx, writer, pixmap->w, pixmap->h, pixmap->n, pixmap->alpha, pixmap->xres, pixmap->yres, 0, pixmap->colorspace, pixmap->seps);
fz_write_band(ctx, writer, pixmap->stride, pixmap->h, pixmap->samples);
}
fz_always(ctx)
@@ -118,7 +118,7 @@ fz_write_bitmap_as_pwg_page(fz_context *ctx, fz_output *out, const fz_bitmap *bi
fz_try(ctx)
{
- fz_write_header(ctx, writer, bitmap->w, bitmap->h, bitmap->n, 0, bitmap->xres, bitmap->yres, 0, NULL);
+ fz_write_header(ctx, writer, bitmap->w, bitmap->h, bitmap->n, 0, bitmap->xres, bitmap->yres, 0, NULL, NULL);
fz_write_band(ctx, writer, bitmap->stride, bitmap->h, bitmap->samples);
}
fz_always(ctx)
@@ -277,6 +277,8 @@ pwg_write_header(fz_context *ctx, fz_band_writer *writer_, const fz_colorspace *
pwg_band_writer *writer = (pwg_band_writer *)writer_;
int n = writer->super.n;
+ if (writer->super.s != 0)
+ fz_throw(ctx, FZ_ERROR_GENERIC, "PWG band writer cannot cope with spot colors");
if (writer->super.alpha != 0)
fz_throw(ctx, FZ_ERROR_GENERIC, "PWG band writer cannot cope with alpha");
if (n != 1 && n != 3 && n != 4)
diff --git a/source/fitz/output-tga.c b/source/fitz/output-tga.c
index f576dd74..4206154a 100644
--- a/source/fitz/output-tga.c
+++ b/source/fitz/output-tga.c
@@ -69,7 +69,7 @@ fz_write_pixmap_as_tga(fz_context *ctx, fz_output *out, fz_pixmap *pixmap)
fz_try(ctx)
{
- fz_write_header(ctx, writer, pixmap->w, pixmap->h, pixmap->n, pixmap->alpha, pixmap->xres, pixmap->yres, 0, pixmap->colorspace);
+ fz_write_header(ctx, writer, pixmap->w, pixmap->h, pixmap->n, pixmap->alpha, pixmap->xres, pixmap->yres, 0, pixmap->colorspace, pixmap->seps);
fz_write_band(ctx, writer, -pixmap->stride, pixmap->h, pixmap->samples + pixmap->stride * (pixmap->h-1));
}
fz_always(ctx)
@@ -90,6 +90,8 @@ tga_write_header(fz_context *ctx, fz_band_writer *writer_, const fz_colorspace *
unsigned char head[18];
int d = (alpha && n > 1) ? 4 : (n == 1 ? 1 : 3);
+ if (writer->super.s != 0)
+ fz_throw(ctx, FZ_ERROR_GENERIC, "TGA writer cannot cope with spot colors");
if (n-alpha > 1 && n != 3+alpha)
fz_throw(ctx, FZ_ERROR_GENERIC, "pixmap must be grayscale/rgb/rgba (with or without alpha) to write as tga");
memset(head, 0, sizeof(head));
diff --git a/source/fitz/output.c b/source/fitz/output.c
index 3240be12..08ee50fe 100644
--- a/source/fitz/output.c
+++ b/source/fitz/output.c
@@ -392,18 +392,21 @@ fz_band_writer *fz_new_band_writer_of_size(fz_context *ctx, size_t size, fz_outp
return writer;
}
-void fz_write_header(fz_context *ctx, fz_band_writer *writer, int w, int h, int n, int alpha, int xres, int yres, int pagenum, const fz_colorspace *cs)
+void fz_write_header(fz_context *ctx, fz_band_writer *writer, int w, int h, int n, int alpha, int xres, int yres, int pagenum, const fz_colorspace *cs, fz_separations *seps)
{
if (writer == NULL || writer->band == NULL)
return;
+
writer->w = w;
writer->h = h;
+ writer->s = fz_count_active_separations(ctx, seps);
writer->n = n;
writer->alpha = alpha;
writer->xres = xres;
writer->yres = yres;
writer->pagenum = pagenum;
writer->line = 0;
+ writer->seps = fz_keep_separations(ctx, seps);
writer->header(ctx, writer, cs);
}
@@ -433,5 +436,6 @@ void fz_drop_band_writer(fz_context *ctx, fz_band_writer *writer)
return;
if (writer->drop != NULL)
writer->drop(ctx, writer);
+ fz_drop_separations(ctx, writer->seps);
fz_free(ctx, writer);
}
diff --git a/source/tools/mudraw.c b/source/tools/mudraw.c
index 1959dddc..9725311d 100644
--- a/source/tools/mudraw.c
+++ b/source/tools/mudraw.c
@@ -825,7 +825,7 @@ static void dodrawpage(fz_context *ctx, fz_page *page, fz_display_list *list, in
}
if (bander)
{
- fz_write_header(ctx, bander, pix->w, totalheight, pix->n, pix->alpha, pix->xres, pix->yres, output_pagenum++, pix->colorspace);
+ fz_write_header(ctx, bander, pix->w, totalheight, pix->n, pix->alpha, pix->xres, pix->yres, output_pagenum++, pix->colorspace, pix->seps);
}
}
diff --git a/source/tools/muraster.c b/source/tools/muraster.c
index cbc8be27..2724a598 100644
--- a/source/tools/muraster.c
+++ b/source/tools/muraster.c
@@ -615,7 +615,7 @@ static int dodrawpage(fz_context *ctx, int pagenum, fz_cookie *cookie, render_de
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);
+ fz_write_header(ctx, render->bander, pix->w, total_height, pix->n, pix->alpha, pix->xres, pix->yres, pagenum, pix->colorspace, pix->seps);
for (band = 0; band < bands; band++)
{
@@ -718,7 +718,7 @@ static int try_render_page(fz_context *ctx, int pagenum, fz_cookie *cookie, int
{
int w = render->ibounds.x1 - render->ibounds.x0;
int h = render->ibounds.y1 - render->ibounds.y0;
- fz_write_header(ctx, render->bander, w, h, render->n, 0, 0, 0, 0, NULL);
+ fz_write_header(ctx, render->bander, w, h, 0, render->n, 0, 0, 0, 0, NULL);
}
fz_catch(ctx)
{