beta-0.89.2
[luatex.git] / source / libs / poppler / poppler-src / goo / JpegWriter.cc
blob9b7c50518389b8f77bf8f64fc8edb11d62f8b8f2
1 //========================================================================
2 //
3 // JpegWriter.cc
4 //
5 // This file is licensed under the GPLv2 or later
6 //
7 // Copyright (C) 2009 Stefan Thomas <thomas@eload24.com>
8 // Copyright (C) 2010, 2012 Adrian Johnson <ajohnson@redneon.com>
9 // Copyright (C) 2010 Harry Roberts <harry.roberts@midnight-labs.org>
10 // Copyright (C) 2011 Thomas Freitag <Thomas.Freitag@alfa.de>
11 // Copyright (C) 2013 Peter Breitenlohner <peb@mppmu.mpg.de>
13 //========================================================================
15 #include "JpegWriter.h"
17 #ifdef ENABLE_LIBJPEG
19 extern "C" {
20 #include <jpeglib.h>
23 #include "poppler/Error.h"
25 struct JpegWriterPrivate {
26 bool progressive;
27 int quality;
28 JpegWriter::Format format;
29 struct jpeg_compress_struct cinfo;
30 struct jpeg_error_mgr jerr;
33 void outputMessage(j_common_ptr cinfo)
35 char buffer[JMSG_LENGTH_MAX];
37 // Create the message
38 (*cinfo->err->format_message) (cinfo, buffer);
40 // Send it to poppler's error handler
41 error(errInternal, -1, "{0:s}", buffer);
44 JpegWriter::JpegWriter(int q, bool p, Format formatA)
46 priv = new JpegWriterPrivate;
47 priv->progressive = p;
48 priv->quality = q;
49 priv->format = formatA;
52 JpegWriter::JpegWriter(Format formatA)
54 priv = new JpegWriterPrivate;
55 priv->progressive = false;
56 priv->quality = -1;
57 priv->format = formatA;
60 JpegWriter::~JpegWriter()
62 // cleanup
63 jpeg_destroy_compress(&priv->cinfo);
64 delete priv;
67 bool JpegWriter::init(FILE *f, int width, int height, int hDPI, int vDPI)
69 // Setup error handler
70 priv->cinfo.err = jpeg_std_error(&priv->jerr);
71 priv->jerr.output_message = &outputMessage;
73 // Initialize libjpeg
74 jpeg_create_compress(&priv->cinfo);
76 // First set colorspace and call jpeg_set_defaults() since
77 // jpeg_set_defaults() sets default values for all fields in
78 // cinfo based on the colorspace.
79 switch (priv->format) {
80 case RGB:
81 priv->cinfo.in_color_space = JCS_RGB;
82 break;
83 case GRAY:
84 priv->cinfo.in_color_space = JCS_GRAYSCALE;
85 break;
86 case CMYK:
87 priv->cinfo.in_color_space = JCS_CMYK;
88 break;
89 default:
90 return false;
92 jpeg_set_defaults(&priv->cinfo);
94 // Set destination file
95 jpeg_stdio_dest(&priv->cinfo, f);
97 // Set libjpeg configuration
98 priv->cinfo.image_width = width;
99 priv->cinfo.image_height = height;
100 priv->cinfo.density_unit = 1; // dots per inch
101 priv->cinfo.X_density = hDPI;
102 priv->cinfo.Y_density = vDPI;
103 switch (priv->format) {
104 case GRAY:
105 priv->cinfo.input_components = 1;
106 break;
107 case RGB:
108 priv->cinfo.input_components = 3;
109 break;
110 case CMYK:
111 priv->cinfo.input_components = 4;
112 jpeg_set_colorspace(&priv->cinfo, JCS_YCCK);
113 priv->cinfo.write_JFIF_header = TRUE;
114 break;
115 default:
116 return false;
119 // Set quality
120 if (priv->quality >= 0 && priv->quality <= 100) {
121 jpeg_set_quality(&priv->cinfo, priv->quality, TRUE);
124 // Use progressive mode
125 if (priv->progressive) {
126 jpeg_simple_progression(&priv->cinfo);
129 // Get ready for data
130 jpeg_start_compress(&priv->cinfo, TRUE);
132 return true;
135 bool JpegWriter::writePointers(unsigned char **rowPointers, int rowCount)
137 if (priv->format == CMYK) {
138 for (int y = 0; y < rowCount; y++) {
139 unsigned char *row = rowPointers[y];
140 for (unsigned int x = 0; x < priv->cinfo.image_width; x++) {
141 for (int n = 0; n < 4; n++) {
142 *row = 0xff - *row;
143 row++;
148 // Write all rows to the file
149 jpeg_write_scanlines(&priv->cinfo, rowPointers, rowCount);
151 return true;
154 bool JpegWriter::writeRow(unsigned char **rowPointer)
156 if (priv->format == CMYK) {
157 unsigned char *row = rowPointer[0];
158 for (unsigned int x = 0; x < priv->cinfo.image_width; x++) {
159 for (int n = 0; n < 4; n++) {
160 *row = 0xff - *row;
161 row++;
165 // Write the row to the file
166 jpeg_write_scanlines(&priv->cinfo, rowPointer, 1);
168 return true;
171 bool JpegWriter::close()
173 jpeg_finish_compress(&priv->cinfo);
175 return true;
178 bool JpegWriter::supportCMYK()
180 return priv->format == CMYK;
184 #endif