diff options
Diffstat (limited to 'source/fitz')
-rw-r--r-- | source/fitz/output-pnm.c | 154 | ||||
-rw-r--r-- | source/fitz/output-psd.c | 73 | ||||
-rw-r--r-- | source/fitz/output-tga.c | 28 |
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]); |