summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/mupdf/fitz.h1
-rw-r--r--include/mupdf/fitz/output-tga.h10
-rw-r--r--source/fitz/pixmap.c79
-rw-r--r--source/tools/mudraw.c12
4 files changed, 99 insertions, 3 deletions
diff --git a/include/mupdf/fitz.h b/include/mupdf/fitz.h
index 6cc13efe..00458e8c 100644
--- a/include/mupdf/fitz.h
+++ b/include/mupdf/fitz.h
@@ -54,5 +54,6 @@
#include "mupdf/fitz/output-pwg.h"
#include "mupdf/fitz/output-pcl.h"
#include "mupdf/fitz/output-svg.h"
+#include "mupdf/fitz/output-tga.h"
#endif
diff --git a/include/mupdf/fitz/output-tga.h b/include/mupdf/fitz/output-tga.h
new file mode 100644
index 00000000..316eb182
--- /dev/null
+++ b/include/mupdf/fitz/output-tga.h
@@ -0,0 +1,10 @@
+#ifndef MUPDF_FITZ_OUTPUT_TGA_H
+#define MUPDF_FITZ_OUTPUT_TGA_H
+
+#include "mupdf/fitz/system.h"
+#include "mupdf/fitz/context.h"
+#include "mupdf/fitz/pixmap.h"
+
+void fz_write_tga(fz_context *ctx, fz_pixmap *pixmap, const char *filename, int savealpha);
+
+#endif
diff --git a/source/fitz/pixmap.c b/source/fitz/pixmap.c
index 8b3ac6a6..8692a468 100644
--- a/source/fitz/pixmap.c
+++ b/source/fitz/pixmap.c
@@ -841,6 +841,85 @@ fz_image_as_png(fz_context *ctx, fz_image *image, int w, int h)
return buf;
}
+/*
+ * Write pixmap to TGA file (with or without alpha channel)
+ */
+
+static inline void tga_put_pixel(unsigned char *data, int n, int is_bgr, fz_output *out)
+{
+ if (n >= 3 && !is_bgr)
+ {
+ fz_putc(out, data[2]);
+ fz_putc(out, data[1]);
+ fz_putc(out, data[0]);
+ if (n == 4)
+ fz_putc(out, data[3]);
+ return;
+ }
+ if (n == 2)
+ {
+ fz_putc(out, data[0]);
+ fz_putc(out, data[0]);
+ }
+ fz_write(out, data, n);
+}
+
+void
+fz_write_tga(fz_context *ctx, fz_pixmap *pixmap, const char *filename, int savealpha)
+{
+ fz_output *out;
+ unsigned char head[18];
+ int n = pixmap->n;
+ int d = savealpha || n == 1 ? n : n - 1;
+ int is_bgr = pixmap->colorspace == fz_device_bgr(ctx);
+ int k;
+
+ if (pixmap->colorspace && pixmap->colorspace != fz_device_gray(ctx) &&
+ pixmap->colorspace != fz_device_rgb(ctx) && pixmap->colorspace != fz_device_bgr(ctx))
+ {
+ fz_throw(ctx, FZ_ERROR_GENERIC, "pixmap must be grayscale or rgb to write as tga");
+ }
+
+ out = fz_new_output_to_filename(ctx, filename);
+
+ memset(head, 0, sizeof(head));
+ head[2] = n == 4 ? 10 : 11;
+ head[12] = pixmap->w & 0xFF; head[13] = (pixmap->w >> 8) & 0xFF;
+ head[14] = pixmap->h & 0xFF; head[15] = (pixmap->h >> 8) & 0xFF;
+ head[16] = d * 8;
+ head[17] = savealpha && n > 1 ? 8 : 0;
+ if (savealpha && d == 2)
+ head[16] = 32;
+
+ fz_write(out, head, sizeof(head));
+ for (k = 1; k <= pixmap->h; k++)
+ {
+ int i, j;
+ unsigned char *line = pixmap->samples + pixmap->w * n * (pixmap->h - k);
+ for (i = 0, j = 1; i < pixmap->w; i += j, j = 1)
+ {
+ for (; i + j < pixmap->w && j < 128 && !memcmp(line + i * n, line + (i + j) * n, d); j++);
+ if (j > 1)
+ {
+ fz_putc(out, j - 1 + 128);
+ tga_put_pixel(line + i * n, d, is_bgr, out);
+ }
+ else
+ {
+ for (; i + j < pixmap->w && j <= 128 && memcmp(line + (i + j - 1) * n, line + (i + j) * n, d) != 0; j++);
+ if (i + j < pixmap->w || j > 128)
+ j--;
+ fz_putc(out, j - 1);
+ for (; j > 0; j--, i++)
+ tga_put_pixel(line + i * n, d, is_bgr, out);
+ }
+ }
+ }
+ fz_write(out, "\0\0\0\0\0\0\0\0TRUEVISION-XFILE.\0", 26);
+
+ fz_close_output(out);
+}
+
unsigned int
fz_pixmap_size(fz_context *ctx, fz_pixmap * pix)
{
diff --git a/source/tools/mudraw.c b/source/tools/mudraw.c
index 81222993..c95be5e3 100644
--- a/source/tools/mudraw.c
+++ b/source/tools/mudraw.c
@@ -14,7 +14,7 @@
enum { TEXT_PLAIN = 1, TEXT_HTML = 2, TEXT_XML = 3 };
-enum { OUT_PNG, OUT_PPM, OUT_PNM, OUT_PAM, OUT_PGM, OUT_PBM, OUT_SVG, OUT_PWG, OUT_PCL, OUT_PDF };
+enum { OUT_PNG, OUT_PPM, OUT_PNM, OUT_PAM, OUT_PGM, OUT_PBM, OUT_SVG, OUT_PWG, OUT_PCL, OUT_PDF, OUT_TGA };
enum { CS_INVALID, CS_UNSET, CS_MONO, CS_GRAY, CS_GRAYALPHA, CS_RGB, CS_RGBA };
@@ -36,6 +36,7 @@ static const suffix_t suffix_table[] =
{ ".pwg", OUT_PWG },
{ ".pcl", OUT_PCL },
{ ".pdf", OUT_PDF },
+ { ".tga", OUT_TGA },
};
typedef struct
@@ -77,7 +78,8 @@ static const format_cs_table_t format_cs_table[] =
{ OUT_SVG, CS_RGB, { CS_RGB } },
{ OUT_PWG, CS_RGB, { CS_MONO, CS_GRAY, CS_RGB } },
{ OUT_PCL, CS_MONO, { CS_MONO } },
- { OUT_PDF, CS_RGB, { CS_RGB } }
+ { OUT_PDF, CS_RGB, { CS_RGB } },
+ { OUT_TGA, CS_RGB, { CS_GRAY, CS_GRAYALPHA, CS_RGB, CS_RGBA } },
};
/*
@@ -183,7 +185,7 @@ static void usage(void)
"usage: mudraw [options] input [pages]\n"
"\t-o -\toutput filename (%%d for page number)\n"
"\t-F -\toutput format (if no -F, -o will be examined)\n"
- "\t\tsupported formats: pgm, ppm, pam, png, pbm\n"
+ "\t\tsupported formats: pgm, ppm, pam, png, pbm, tga\n"
"\t-p -\tpassword\n"
"\t-r -\tresolution in dpi (default: 72)\n"
"\t-w -\twidth (in pixels) (maximum width if -r is specified)\n"
@@ -758,6 +760,10 @@ static void drawpage(fz_context *ctx, fz_document *doc, int pagenum)
fz_write_pbm(ctx, bit, filename_buf);
fz_drop_bitmap(ctx, bit);
}
+ else if (output_format == OUT_TGA)
+ {
+ fz_write_tga(ctx, pix, filename_buf, savealpha);
+ }
}
ctm.f -= drawheight;
}