summaryrefslogtreecommitdiff
path: root/Build/source/libs/poppler/poppler-0.18.4/goo/JpegWriter.cc
blob: 9b6645b82a086fafd3eb2491db0d567c92ccffa9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
//========================================================================
//
// JpegWriter.cc
//
// This file is licensed under the GPLv2 or later
//
// Copyright (C) 2009 Stefan Thomas <thomas@eload24.com>
// Copyright (C) 2010, 2012 Adrian Johnson <ajohnson@redneon.com>
// Copyright (C) 2010 Harry Roberts <harry.roberts@midnight-labs.org>
// Copyright (C) 2011 Thomas Freitag <Thomas.Freitag@alfa.de>
//
//========================================================================

#include "JpegWriter.h"

#ifdef ENABLE_LIBJPEG

#include "poppler/Error.h"

void outputMessage(j_common_ptr cinfo)
{
	char buffer[JMSG_LENGTH_MAX];

	// Create the message
	(*cinfo->err->format_message) (cinfo, buffer);

	// Send it to poppler's error handler
	error(-1, "%s", buffer);
}

JpegWriter::JpegWriter(int q, bool p, J_COLOR_SPACE cm)
: progressive(p), quality(q), colorMode(cm)
{
}

JpegWriter::JpegWriter(J_COLOR_SPACE cm)
: progressive(false), quality(-1), colorMode(cm)
{
}

JpegWriter::~JpegWriter()
{
	// cleanup
	jpeg_destroy_compress(&cinfo);
}

bool JpegWriter::init(FILE *f, int width, int height, int hDPI, int vDPI)
{
	// Setup error handler
	cinfo.err = jpeg_std_error(&jerr);
	jerr.output_message = &outputMessage;

	// Initialize libjpeg
	jpeg_create_compress(&cinfo);
	
        // Set colorspace and initialise defaults
	cinfo.in_color_space = colorMode; /* colorspace of input image */
	jpeg_set_defaults(&cinfo);

	// Set destination file
	jpeg_stdio_dest(&cinfo, f);
	
	// Set libjpeg configuration
	cinfo.image_width = width;
	cinfo.image_height = height;
	cinfo.density_unit = 1; // dots per inch
	cinfo.X_density = hDPI;
	cinfo.Y_density = vDPI;
	/* # of color components per pixel */
	switch (colorMode) {
		case JCS_GRAYSCALE:
			cinfo.input_components = 1;     
			break;
		case JCS_RGB:
			cinfo.input_components = 3;     
			break;
		case JCS_CMYK:
			cinfo.input_components = 4;     
			break;
		default:
			return false;
	}
	if (cinfo.in_color_space == JCS_CMYK) {
		jpeg_set_colorspace(&cinfo, JCS_YCCK);
		cinfo.write_JFIF_header = TRUE;
	}
	
	// Set quality
	if( quality >= 0 && quality <= 100 ) { 
		jpeg_set_quality(&cinfo, quality, true);
	}
	
	// Use progressive mode
	if( progressive) {
		jpeg_simple_progression(&cinfo);
	}
	
	// Get ready for data
	jpeg_start_compress(&cinfo, TRUE);
	
	return true;
}

bool JpegWriter::writePointers(unsigned char **rowPointers, int rowCount)
{
	if (colorMode == JCS_CMYK) {
		for (int y = 0; y < rowCount; y++) {
			unsigned char *row = rowPointers[y];
			for (unsigned int x = 0; x < cinfo.image_width; x++) {
				for (int n = 0; n < 4; n++) {
					*row = 0xff - *row;
					row++;
				}
			}
		}
	}
	// Write all rows to the file
	jpeg_write_scanlines(&cinfo, rowPointers, rowCount);
	
	return true;
}

bool JpegWriter::writeRow(unsigned char **rowPointer)
{
	if (colorMode == JCS_CMYK) {
		unsigned char *row = rowPointer[0];
		for (unsigned int x = 0; x < cinfo.image_width; x++) {
			for (int n = 0; n < 4; n++) {
				*row = 0xff - *row;
				row++;
			}
		}
	}
	// Write the row to the file
	jpeg_write_scanlines(&cinfo, rowPointer, 1);
	
	return true;
}

bool JpegWriter::close()
{
	jpeg_finish_compress(&cinfo);
	
	return true;
}

#endif