summaryrefslogtreecommitdiff
path: root/source/fitz/output-pnm.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/fitz/output-pnm.c')
-rw-r--r--source/fitz/output-pnm.c154
1 files changed, 112 insertions, 42 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)