summaryrefslogtreecommitdiff
path: root/source/fitz
diff options
context:
space:
mode:
Diffstat (limited to 'source/fitz')
-rw-r--r--source/fitz/output-pnm.c154
-rw-r--r--source/fitz/output-psd.c73
-rw-r--r--source/fitz/output-tga.c28
3 files changed, 195 insertions, 60 deletions
diff --git a/source/fitz/output-pnm.c b/source/fitz/output-pnm.c
index 9bc5e6aa..598d66f6 100644
--- a/source/fitz/output-pnm.c
+++ b/source/fitz/output-pnm.c
@@ -15,6 +15,9 @@ pnm_write_header(fz_context *ctx, fz_band_writer *writer, const fz_colorspace *c
if (writer->s != 0)
fz_throw(ctx, FZ_ERROR_GENERIC, "PNM writer cannot cope with spot colors");
+ if (alpha)
+ fz_throw(ctx, FZ_ERROR_GENERIC, "PNM writer cannot cope with alpha");
+
n -= alpha;
if (n != 1 && n != 3)
fz_throw(ctx, FZ_ERROR_GENERIC, "pixmap must be grayscale or rgb to write as pnm");
@@ -34,12 +37,10 @@ pnm_write_band(fz_context *ctx, fz_band_writer *writer, int stride, int band_sta
int w = writer->w;
int h = writer->h;
int n = writer->n;
- int alpha = writer->alpha;
- char buffer[2*3*4*5*6]; /* Buffer must be a multiple of 2 and 3 at least. */
int len;
int end = band_start + band_height;
- if (n-alpha != 1 && n-alpha != 3)
+ if (n != 1 && n != 3)
fz_throw(ctx, FZ_ERROR_GENERIC, "pixmap must be grayscale or rgb to write as pnm");
if (!out)
@@ -67,44 +68,10 @@ pnm_write_band(fz_context *ctx, fz_band_writer *writer, int stride, int band_sta
fz_write_data(ctx, out, p, num_written);
p += num_written;
break;
- case 2:
- {
- char *o = buffer;
- int count;
-
- if (num_written > sizeof(buffer))
- num_written = sizeof(buffer);
-
- for (count = num_written; count; count--)
- {
- *o++ = *p;
- p += 2;
- }
- fz_write_data(ctx, out, buffer, num_written);
- break;
- }
case 3:
fz_write_data(ctx, out, p, num_written*3);
p += num_written*3;
break;
- case 4:
- {
- char *o = buffer;
- int count;
-
- if (num_written > sizeof(buffer)/3)
- num_written = sizeof(buffer)/3;
-
- for (count = num_written; count; count--)
- {
- *o++ = p[0];
- *o++ = p[1];
- *o++ = p[2];
- p += n;
- }
- fz_write_data(ctx, out, buffer, num_written * 3);
- break;
- }
}
len -= num_written;
}
@@ -191,7 +158,7 @@ pam_write_header(fz_context *ctx, fz_band_writer *writer, const fz_colorspace *c
else if (n == 3 && !alpha) fz_write_printf(ctx, out, "TUPLTYPE RGB\n");
else if (n == 3 && alpha) fz_write_printf(ctx, out, "TUPLTYPE RGB_ALPHA\n");
else if (n == 4 && !alpha) fz_write_printf(ctx, out, "TUPLTYPE CMYK\n");
- else if (n == 5) fz_write_printf(ctx, out, "TUPLTYPE CMYK_ALPHA\n");
+ else if (n == 4 && alpha) fz_write_printf(ctx, out, "TUPLTYPE CMYK_ALPHA\n");
fz_write_printf(ctx, out, "ENDHDR\n");
}
@@ -202,7 +169,8 @@ pam_write_band(fz_context *ctx, fz_band_writer *writer, int stride, int band_sta
int w = writer->w;
int h = writer->h;
int n = writer->n;
- int y;
+ int alpha = writer->alpha;
+ int x, y;
int end = band_start + band_height;
if (!out)
@@ -212,11 +180,113 @@ pam_write_band(fz_context *ctx, fz_band_writer *writer, int stride, int band_sta
end = h;
end -= band_start;
- for (y = 0; y < end; y++)
+ if (alpha)
{
- fz_write_data(ctx, out, sp, w * n);
- sp += stride;
+ /* Buffer must be a multiple of 2, 3 and 5 at least. */
+ /* Also, for the generic case, it must be bigger than FZ_MAX_COLORS */
+ char buffer[2*3*4*5*6];
+ char *b = buffer;
+ stride -= n * w;
+ switch (n)
+ {
+ case 2:
+ for (y = 0; y < end; y++)
+ {
+ for (x = 0; x < w; x++)
+ {
+ int a = sp[1];
+ *b++ = a ? (sp[0] * 255 + (a>>1))/a : 0;
+ *b++ = a;
+ sp += 2;
+ if (b == &buffer[sizeof(buffer)])
+ {
+ fz_write_data(ctx, out, buffer, sizeof(buffer));
+ b = buffer;
+ }
+ }
+ sp += stride;
+ }
+ if (b != buffer)
+ fz_write_data(ctx, out, buffer, b - buffer);
+ break;
+ case 4:
+ for (y = 0; y < end; y++)
+ {
+ for (x = 0; x < w; x++)
+ {
+ int a = sp[3];
+ int inva = a ? 256 * 255 / a : 0;
+ *b++ = (sp[0] * inva + 128)>>8;
+ *b++ = (sp[1] * inva + 128)>>8;
+ *b++ = (sp[2] * inva + 128)>>8;
+ *b++ = a;
+ sp += 4;
+ if (b == &buffer[sizeof(buffer)])
+ {
+ fz_write_data(ctx, out, buffer, sizeof(buffer));
+ b = buffer;
+ }
+ }
+ sp += stride;
+ }
+ if (b != buffer)
+ fz_write_data(ctx, out, buffer, b - buffer);
+ break;
+ case 5:
+ for (y = 0; y < end; y++)
+ {
+ for (x = 0; x < w; x++)
+ {
+ int a = sp[4];
+ int inva = a ? 256 * 255 / a : 0;
+ *b++ = (sp[0] * inva + 128)>>8;
+ *b++ = (sp[1] * inva + 128)>>8;
+ *b++ = (sp[2] * inva + 128)>>8;
+ *b++ = (sp[3] * inva + 128)>>8;
+ *b++ = a;
+ sp += 5;
+ if (b == &buffer[sizeof(buffer)])
+ {
+ fz_write_data(ctx, out, buffer, sizeof(buffer));
+ b = buffer;
+ }
+ }
+ sp += stride;
+ }
+ if (b != buffer)
+ fz_write_data(ctx, out, buffer, b - buffer);
+ break;
+ default:
+ for (y = 0; y < end; y++)
+ {
+ for (x = 0; x < w; x++)
+ {
+ int a = sp[n-1];
+ int inva = a ? 256 * 255 / a : 0;
+ int k;
+ for (k = 0; k < n-1; k++)
+ *b++ = (*sp++ * inva + 128)>>8;
+ *b++ = a;
+ sp++;
+ if (b >= &buffer[sizeof(buffer)] - n)
+ {
+ fz_write_data(ctx, out, buffer, b - buffer);
+ b = buffer;
+ }
+ }
+ sp += stride;
+ }
+ if (b != buffer)
+ fz_write_data(ctx, out, buffer, b - buffer);
+ break;
+ }
}
+ else
+ for (y = 0; y < end; y++)
+ {
+ fz_write_data(ctx, out, sp, w * n);
+ sp += stride;
+ }
}
fz_band_writer *fz_new_pam_band_writer(fz_context *ctx, fz_output *out)
diff --git a/source/fitz/output-psd.c b/source/fitz/output-psd.c
index 223a591e..e097e9a6 100644
--- a/source/fitz/output-psd.c
+++ b/source/fitz/output-psd.c
@@ -254,8 +254,41 @@ psd_write_band(fz_context *ctx, fz_band_writer *writer_, int stride, int band_st
plane_inc = w * (h - band_height);
line_skip = stride - w*n;
b = buffer;
- for (k = 0; k < n; k++)
+ if (writer->super.alpha)
{
+ const unsigned char *ap = &sp[n-1];
+ for (k = 0; k < n-1; k++)
+ {
+ for (y = 0; y < band_height; y++)
+ {
+ for (x = 0; x < w; x++)
+ {
+ int a = *ap;
+ ap += n;
+ *b++ = a != 0 ? (*sp * 255 + 128)/a : 0;
+ 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;
+ }
+ }
+ sp += line_skip;
+ ap += line_skip;
+ }
+ sp -= stride * band_height - 1;
+ ap -= stride * band_height;
+ if (b != buffer)
+ {
+ if (k >= num_additive)
+ psd_invert_buffer(buffer, sizeof(buffer));
+ fz_write_data(ctx, out, buffer, b - buffer);
+ b = buffer;
+ }
+ fz_seek_output(ctx, out, plane_inc, SEEK_CUR);
+ }
for (y = 0; y < band_height; y++)
{
for (x = 0; x < w; x++)
@@ -264,25 +297,51 @@ 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;
}
}
sp += line_skip;
}
- 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;
}
fz_seek_output(ctx, out, plane_inc, SEEK_CUR);
}
- fz_seek_output(ctx, out, w * h * (1-n), SEEK_CUR);
+ else
+ {
+ for (k = 0; k < n; k++)
+ {
+ for (y = 0; y < band_height; y++)
+ {
+ for (x = 0; x < w; x++)
+ {
+ *b++ = *sp;
+ 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;
+ }
+ }
+ sp += line_skip;
+ }
+ 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;
+ }
+ fz_seek_output(ctx, out, plane_inc, SEEK_CUR);
+ }
+ }
+ fz_seek_output(ctx, out, w * (band_height - h * n), SEEK_CUR);
}
static void
diff --git a/source/fitz/output-tga.c b/source/fitz/output-tga.c
index 3bee3640..0e7a213c 100644
--- a/source/fitz/output-tga.c
+++ b/source/fitz/output-tga.c
@@ -13,19 +13,22 @@ typedef struct {
static inline void tga_put_pixel(fz_context *ctx, fz_output *out, const unsigned char *data, int n, int is_bgr)
{
+ int a, inva;
switch(n)
{
case 4: /* RGBA or BGRA */
+ a = data[3];
+ inva = a ? 256 * 255 / a : 0;
if (!is_bgr) {
- fz_write_byte(ctx, out, data[2]);
- fz_write_byte(ctx, out, data[1]);
- fz_write_byte(ctx, out, data[0]);
+ fz_write_byte(ctx, out, (data[2] * inva + 128)>>8);
+ fz_write_byte(ctx, out, (data[1] * inva + 128)>>8);
+ fz_write_byte(ctx, out, (data[0] * inva + 128)>>8);
} else {
- fz_write_byte(ctx, out, data[0]);
- fz_write_byte(ctx, out, data[1]);
- fz_write_byte(ctx, out, data[2]);
+ fz_write_byte(ctx, out, (data[0] * inva + 128)>>8);
+ fz_write_byte(ctx, out, (data[1] * inva + 128)>>8);
+ fz_write_byte(ctx, out, (data[2] * inva + 128)>>8);
}
- fz_write_byte(ctx, out, data[3]);
+ fz_write_byte(ctx, out, a);
break;
case 3: /* RGB or BGR */
if (!is_bgr) {
@@ -39,10 +42,13 @@ static inline void tga_put_pixel(fz_context *ctx, fz_output *out, const unsigned
}
break;
case 2: /* GA */
- fz_write_byte(ctx, out, data[0]);
- fz_write_byte(ctx, out, data[0]);
- fz_write_byte(ctx, out, data[0]);
- fz_write_byte(ctx, out, data[1]);
+ a = data[1];
+ inva = a ? 256 * 255 / a : 0;
+ inva = (data[0] * inva + 128)>>8;
+ fz_write_byte(ctx, out, inva);
+ fz_write_byte(ctx, out, inva);
+ fz_write_byte(ctx, out, inva);
+ fz_write_byte(ctx, out, a);
break;
case 1: /* G */
fz_write_byte(ctx, out, data[0]);