summaryrefslogtreecommitdiff
path: root/Build/source/texk/web2c/luatexdir/image/writejpg.c
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/texk/web2c/luatexdir/image/writejpg.c')
-rw-r--r--Build/source/texk/web2c/luatexdir/image/writejpg.c277
1 files changed, 277 insertions, 0 deletions
diff --git a/Build/source/texk/web2c/luatexdir/image/writejpg.c b/Build/source/texk/web2c/luatexdir/image/writejpg.c
new file mode 100644
index 00000000000..422c29470fb
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/image/writejpg.c
@@ -0,0 +1,277 @@
+/*
+Copyright (c) 1996-2006 Han The Thanh, <thanh@pdftex.org>
+
+This file is part of pdfTeX.
+pdfTeX is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+pdfTeX is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with pdfTeX; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+$Id: writejpg.c 1100 2008-03-09 13:40:48Z hhenkel $
+*/
+
+#include <assert.h>
+#include "ptexlib.h"
+#include "image.h"
+
+#define JPG_GRAY 1 /* Gray color space, use /DeviceGray */
+#define JPG_RGB 3 /* RGB color space, use /DeviceRGB */
+#define JPG_CMYK 4 /* CMYK color space, use /DeviceCMYK */
+
+typedef enum { /* JPEG marker codes */
+ M_SOF0 = 0xc0, /* baseline DCT */
+ M_SOF1 = 0xc1, /* extended sequential DCT */
+ M_SOF2 = 0xc2, /* progressive DCT */
+ M_SOF3 = 0xc3, /* lossless (sequential) */
+
+ M_SOF5 = 0xc5, /* differential sequential DCT */
+ M_SOF6 = 0xc6, /* differential progressive DCT */
+ M_SOF7 = 0xc7, /* differential lossless */
+
+ M_JPG = 0xc8, /* JPEG extensions */
+ M_SOF9 = 0xc9, /* extended sequential DCT */
+ M_SOF10 = 0xca, /* progressive DCT */
+ M_SOF11 = 0xcb, /* lossless (sequential) */
+
+ M_SOF13 = 0xcd, /* differential sequential DCT */
+ M_SOF14 = 0xce, /* differential progressive DCT */
+ M_SOF15 = 0xcf, /* differential lossless */
+
+ M_DHT = 0xc4, /* define Huffman tables */
+
+ M_DAC = 0xcc, /* define arithmetic conditioning table */
+
+ M_RST0 = 0xd0, /* restart */
+ M_RST1 = 0xd1, /* restart */
+ M_RST2 = 0xd2, /* restart */
+ M_RST3 = 0xd3, /* restart */
+ M_RST4 = 0xd4, /* restart */
+ M_RST5 = 0xd5, /* restart */
+ M_RST6 = 0xd6, /* restart */
+ M_RST7 = 0xd7, /* restart */
+
+ M_SOI = 0xd8, /* start of image */
+ M_EOI = 0xd9, /* end of image */
+ M_SOS = 0xda, /* start of scan */
+ M_DQT = 0xdb, /* define quantization tables */
+ M_DNL = 0xdc, /* define number of lines */
+ M_DRI = 0xdd, /* define restart interval */
+ M_DHP = 0xde, /* define hierarchical progression */
+ M_EXP = 0xdf, /* expand reference image(s) */
+
+ M_APP0 = 0xe0, /* application marker, used for JFIF */
+ M_APP1 = 0xe1, /* application marker */
+ M_APP2 = 0xe2, /* application marker */
+ M_APP3 = 0xe3, /* application marker */
+ M_APP4 = 0xe4, /* application marker */
+ M_APP5 = 0xe5, /* application marker */
+ M_APP6 = 0xe6, /* application marker */
+ M_APP7 = 0xe7, /* application marker */
+ M_APP8 = 0xe8, /* application marker */
+ M_APP9 = 0xe9, /* application marker */
+ M_APP10 = 0xea, /* application marker */
+ M_APP11 = 0xeb, /* application marker */
+ M_APP12 = 0xec, /* application marker */
+ M_APP13 = 0xed, /* application marker */
+ M_APP14 = 0xee, /* application marker, used by Adobe */
+ M_APP15 = 0xef, /* application marker */
+
+ M_JPG0 = 0xf0, /* reserved for JPEG extensions */
+ M_JPG13 = 0xfd, /* reserved for JPEG extensions */
+ M_COM = 0xfe, /* comment */
+
+ M_TEM = 0x01, /* temporary use */
+
+ M_ERROR = 0x100 /* dummy marker, internal use only */
+} JPEG_MARKER;
+
+static JPG_UINT16 read2bytes(FILE * f)
+{
+ int c = xgetc(f);
+ return (c << 8) + xgetc(f);
+}
+
+void close_and_cleanup_jpg(image_dict * idict)
+{
+ assert(idict != NULL);
+ assert(img_file(idict) != NULL);
+ assert(img_filepath(idict) != NULL);
+ xfclose(img_file(idict), img_filepath(idict));
+ img_file(idict) = NULL;
+ assert(img_jpg_ptr(idict) != NULL);
+ xfree(img_jpg_ptr(idict));
+ img_jpg_ptr(idict) = NULL;
+}
+
+void read_jpg_info(image_dict * idict, img_readtype_e readtype)
+{
+ int i, units = 0;
+ unsigned char jpg_id[] = "JFIF";
+ assert(idict != NULL);
+ assert(img_type(idict) == IMAGE_TYPE_JPG);
+ img_totalpages(idict) = 1;
+ img_pagenum(idict) = 1;
+ img_xres(idict) = img_yres(idict) = 0;
+ assert(img_file(idict) == NULL);
+ img_file(idict) = xfopen(img_filepath(idict), FOPEN_RBIN_MODE);
+ assert(img_jpg_ptr(idict) == NULL);
+ img_jpg_ptr(idict) = xtalloc(1, jpg_img_struct);
+ xfseek(img_file(idict), 0, SEEK_END, img_filepath(idict));
+ img_jpg_ptr(idict)->length = xftell(img_file(idict), img_filepath(idict));
+ xfseek(img_file(idict), 0, SEEK_SET, img_filepath(idict));
+ if (read2bytes(img_file(idict)) != 0xFFD8)
+ pdftex_fail("reading JPEG image failed (no JPEG header found)");
+ /* currently only true JFIF files allow extracting img_xres and img_yres */
+ if (read2bytes(img_file(idict)) == 0xFFE0) { /* check for JFIF */
+ (void) read2bytes(img_file(idict));
+ for (i = 0; i < 5; i++) {
+ if (xgetc(img_file(idict)) != jpg_id[i])
+ break;
+ }
+ if (i == 5) { /* it's JFIF */
+ read2bytes(img_file(idict));
+ units = xgetc(img_file(idict));
+ img_xres(idict) = read2bytes(img_file(idict));
+ img_yres(idict) = read2bytes(img_file(idict));
+ switch (units) {
+ case 1:
+ break; /* pixels per inch */
+ case 2:
+ img_xres(idict) *= 2.54;
+ img_yres(idict) *= 2.54;
+ break; /* pixels per cm */
+ default:
+ img_xres(idict) = img_yres(idict) = 0;
+ break;
+ }
+ }
+ }
+ xfseek(img_file(idict), 0, SEEK_SET, img_filepath(idict));
+ while (1) {
+ if (feof(img_file(idict)))
+ pdftex_fail("reading JPEG image failed (premature file end)");
+ if (fgetc(img_file(idict)) != 0xFF)
+ pdftex_fail("reading JPEG image failed (no marker found)");
+ switch (xgetc(img_file(idict))) {
+ case M_SOF5:
+ case M_SOF6:
+ case M_SOF7:
+ case M_SOF9:
+ case M_SOF10:
+ case M_SOF11:
+ case M_SOF13:
+ case M_SOF14:
+ case M_SOF15:
+ pdftex_fail("unsupported type of compression");
+ case M_SOF2:
+ if (fixed_pdf_minor_version <= 2)
+ pdftex_fail("cannot use progressive DCT with PDF-1.2");
+ case M_SOF0:
+ case M_SOF1:
+ case M_SOF3:
+ (void) read2bytes(img_file(idict)); /* read segment length */
+ img_colordepth(idict) = xgetc(img_file(idict));
+ img_ysize(idict) = read2bytes(img_file(idict));
+ img_xsize(idict) = read2bytes(img_file(idict));
+ img_jpg_color(idict) = xgetc(img_file(idict));
+ xfseek(img_file(idict), 0, SEEK_SET, img_filepath(idict));
+ switch (img_jpg_color(idict)) {
+ case JPG_GRAY:
+ img_color(idict) = IMAGE_COLOR_B;
+ break;
+ case JPG_RGB:
+ img_color(idict) = IMAGE_COLOR_C;
+ break;
+ case JPG_CMYK:
+ img_color(idict) = IMAGE_COLOR_C;
+ break;
+ default:
+ pdftex_fail("Unsupported color space %i",
+ (int) img_jpg_color(idict));
+ }
+ if (readtype == IMG_CLOSEINBETWEEN)
+ close_and_cleanup_jpg(idict);
+ return;
+ case M_SOI: /* ignore markers without parameters */
+ case M_EOI:
+ case M_TEM:
+ case M_RST0:
+ case M_RST1:
+ case M_RST2:
+ case M_RST3:
+ case M_RST4:
+ case M_RST5:
+ case M_RST6:
+ case M_RST7:
+ break;
+ default: /* skip variable length markers */
+ xfseek(img_file(idict), read2bytes(img_file(idict)) - 2,
+ SEEK_CUR, img_filepath(idict));
+ break;
+ }
+ }
+ assert(0);
+}
+
+static void reopen_jpg(image_dict * idict)
+{
+ integer width, height, xres, yres;
+ width = img_xsize(idict);
+ height = img_ysize(idict);
+ xres = img_xres(idict);
+ yres = img_yres(idict);
+ read_jpg_info(idict, IMG_KEEPOPEN);
+ if (width != img_xsize(idict) || height != img_ysize(idict)
+ || xres != img_xres(idict) || yres != img_yres(idict))
+ pdftex_fail("writejpg: image dimensions have changed");
+}
+
+void write_jpg(image_dict * idict)
+{
+ long unsigned l;
+ FILE *f;
+ assert(idict != NULL);
+ if (img_file(idict) == NULL)
+ reopen_jpg(idict);
+ assert(img_jpg_ptr(idict) != NULL);
+ pdf_puts("/Type /XObject\n/Subtype /Image\n");
+ if (img_attr(idict) != NULL && strlen(img_attr(idict)) > 0)
+ pdf_printf("%s\n", img_attr(idict));
+ pdf_printf("/Width %i\n/Height %i\n/BitsPerComponent %i\n/Length %i\n",
+ (int) img_xsize(idict),
+ (int) img_ysize(idict),
+ (int) img_colordepth(idict), (int) img_jpg_ptr(idict)->length);
+ pdf_puts("/ColorSpace ");
+ if (img_colorspace(idict) != 0) {
+ pdf_printf("%i 0 R\n", (int) img_colorspace(idict));
+ } else {
+ switch (img_jpg_color(idict)) {
+ case JPG_GRAY:
+ pdf_puts("/DeviceGray\n");
+ break;
+ case JPG_RGB:
+ pdf_puts("/DeviceRGB\n");
+ break;
+ case JPG_CMYK:
+ pdf_puts("/DeviceCMYK\n/Decode [1 0 1 0 1 0 1 0]\n");
+ break;
+ default:
+ pdftex_fail("Unsupported color space %i",
+ (int) img_jpg_color(idict));
+ }
+ }
+ pdf_puts("/Filter /DCTDecode\n>>\nstream\n");
+ for (l = img_jpg_ptr(idict)->length, f = img_file(idict); l > 0; l--)
+ pdfout(xgetc(f));
+ pdf_end_stream();
+ close_and_cleanup_jpg(idict);
+}