2
* beryl-plugins::jpeg.c - adds JPEG image support to beryl.
3
* Copyright: (C) 2006 Nicholas Thomas
4
* Danny Baumann (JPEG writing, option stuff)
6
* This program is free software; you can redistribute it and/or
7
* modify it under the terms of the GNU General Public License
8
* as published by the Free Software Foundation; either version 2
9
* of the License, or (at your option) any later version.
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
24
COMPIZ_PLUGIN_20090315 (imgjpeg, JpegPluginVTable)
27
rgbToBGRA (const JSAMPLE *source,
34
int height = size.height ();
35
int width = size.width ();
37
dest = (char *) malloc ((unsigned)(height * width * 4));
43
for (h = 0; h < height; h++)
44
for (w = 0; w < width; w++)
46
int pos = h * width + w;
47
#if __BYTE_ORDER == __BIG_ENDIAN
48
dest[(pos * 4) + 3] = source[(pos * 3) + 2]; /* blue */
49
dest[(pos * 4) + 2] = source[(pos * 3) + 1]; /* green */
50
dest[(pos * 4) + 1] = source[(pos * 3) + 0]; /* red */
51
dest[(pos * 4) + 0] = alpha;
53
dest[(pos * 4) + 0] = (char)source[(pos * 3) + 2]; /* blue */
54
dest[(pos * 4) + 1] = (char)source[(pos * 3) + 1]; /* green */
55
dest[(pos * 4) + 2] = (char)source[(pos * 3) + 0]; /* red */
56
dest[(pos * 4) + 3] = alpha;
64
rgbaToRGB (unsigned char *source,
70
int height = size.height ();
71
int width = size.width ();
72
int ps = stride / width; /* pixel size */
75
d = (JSAMPLE *) malloc ((unsigned)height * (unsigned)width * 3 *
82
for (h = 0; h < height; h++)
83
for (w = 0; w < width; w++)
85
int pos = h * width + w;
86
#if __BYTE_ORDER == __BIG_ENDIAN
87
d[(pos * 3) + 0] = source[(pos * ps) + 3]; /* red */
88
d[(pos * 3) + 1] = source[(pos * ps) + 2]; /* green */
89
d[(pos * 3) + 2] = source[(pos * ps) + 1]; /* blue */
91
d[(pos * 3) + 0] = source[(pos * ps) + 0]; /* red */
92
d[(pos * 3) + 1] = source[(pos * ps) + 1]; /* green */
93
d[(pos * 3) + 2] = source[(pos * ps) + 2]; /* blue */
101
jpegErrorExit (j_common_ptr cinfo)
103
char buffer[JMSG_LENGTH_MAX];
104
struct jpegErrorMgr *err = (struct jpegErrorMgr *) cinfo->err;
106
/* Format the message */
107
(*cinfo->err->format_message) (cinfo, buffer);
109
printf ("%s\n", buffer);
111
/* Return control to the setjmp point */
112
longjmp (err->setjmp_buffer, 1);
116
JpegScreen::readJPEG (FILE *file,
120
struct jpeg_decompress_struct cinfo;
121
struct jpegErrorMgr jerr;
129
cinfo.err = jpeg_std_error (&jerr.pub);
130
jerr.pub.error_exit = jpegErrorExit;
132
if (setjmp (jerr.setjmp_buffer))
134
/* this is called on decompression errors */
135
jpeg_destroy_decompress (&cinfo);
139
jpeg_create_decompress (&cinfo);
141
jpeg_stdio_src (&cinfo, file);
143
jpeg_read_header (&cinfo, true);
145
cinfo.out_color_space = JCS_RGB;
147
jpeg_start_decompress (&cinfo);
149
size.setHeight ((int)cinfo.output_height);
150
size.setWidth ((int)cinfo.output_width);
152
buf = (JSAMPLE *) calloc (cinfo.output_height * cinfo.output_width *
153
(unsigned)cinfo.output_components,
157
jpeg_finish_decompress (&cinfo);
158
jpeg_destroy_decompress (&cinfo);
162
rows = (JSAMPROW *) malloc (cinfo.output_height * sizeof (JSAMPROW));
166
jpeg_finish_decompress (&cinfo);
167
jpeg_destroy_decompress (&cinfo);
171
for (unsigned int i = 0; i < cinfo.output_height; i++)
172
rows[i] = &buf[i * cinfo.output_width *
173
(unsigned)cinfo.output_components];
175
while (cinfo.output_scanline < cinfo.output_height)
176
jpeg_read_scanlines (&cinfo, &rows[cinfo.output_scanline],
177
cinfo.output_height - cinfo.output_scanline);
179
jpeg_finish_decompress (&cinfo);
180
jpeg_destroy_decompress (&cinfo);
182
/* convert the rgb data into BGRA format */
183
result = rgbToBGRA (buf, data, size, 255);
191
JpegScreen::writeJPEG (unsigned char *buffer,
196
struct jpeg_compress_struct cinfo;
197
struct jpeg_error_mgr jerr;
198
JSAMPROW row_pointer[1];
201
/* convert the rgb data into BGRA format */
202
if (!rgbaToRGB (buffer, &data, size, stride))
205
cinfo.err = jpeg_std_error (&jerr);
206
jpeg_create_compress (&cinfo);
208
jpeg_stdio_dest (&cinfo, file);
210
cinfo.image_width = (unsigned) size.width ();
211
cinfo.image_height = (unsigned) size.height ();
212
cinfo.input_components = 3;
213
cinfo.in_color_space = JCS_RGB;
215
jpeg_set_defaults (&cinfo);
216
jpeg_set_quality (&cinfo, optionGetQuality (), true);
217
jpeg_start_compress (&cinfo, true);
219
while (cinfo.next_scanline < cinfo.image_height)
222
&data[(cinfo.image_height - cinfo.next_scanline - 1) *
223
(unsigned) size.width () * 3];
224
jpeg_write_scanlines (&cinfo, row_pointer, 1);
227
jpeg_finish_compress (&cinfo);
228
jpeg_destroy_compress (&cinfo);
236
JpegScreen::fileNameWithExtension (CompString &path)
238
unsigned int len = path.length ();
240
if ((len > 5 && path.substr (len - 5, 5) == ".jpeg") ||
241
(len > 4 && path.substr (len - 4, 4) == ".jpg"))
244
return path + ".jpeg";
248
JpegScreen::imageToFile (CompString &path,
256
CompString fileName = fileNameWithExtension (path);
258
if (format == "jpeg" || format == "jpg" ||
259
!(status = screen->imageToFile (path, format, size, stride, data)))
261
file = fopen (fileName.c_str (), "wb");
264
status = writeJPEG ((unsigned char *) data, file, size, stride);
273
JpegScreen::fileToImage (CompString &name,
280
CompString fileName = fileNameWithExtension (name);
282
file = fopen (fileName.c_str (), "rb");
285
status = readJPEG (file, size, data);
291
stride = size.width () * 4;
295
/* Isn't a JPEG - pass to the next in the chain. */
296
return screen->fileToImage (name, size, stride, data);
299
JpegScreen::JpegScreen (CompScreen *screen) :
300
PluginClassHandler<JpegScreen, CompScreen> (screen)
302
ScreenInterface::setHandler (screen, true);
306
JpegPluginVTable::init ()
308
if (!CompPlugin::checkPluginABI ("core", CORE_ABIVERSION))