~linaro-graphics-wg/compiz-plugins-main/oneiric-gles2

« back to all changes in this revision

Viewing changes to jpeg/src/imgjpeg.cpp

  • Committer: Sam Spilsbury
  • Date: 2011-09-20 07:43:55 UTC
  • Revision ID: sam.spilsbury@canonical.com-20110920074355-puzdutejjwsu3ta2
Sync - Remove Plugins

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * beryl-plugins::jpeg.c - adds JPEG image support to beryl.
3
 
 * Copyright: (C) 2006 Nicholas Thomas
4
 
 *                     Danny Baumann (JPEG writing, option stuff)
5
 
 *
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.
10
 
 *
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.
15
 
 *
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.
19
 
 *
20
 
 */
21
 
 
22
 
#include "imgjpeg.h"
23
 
 
24
 
COMPIZ_PLUGIN_20090315 (imgjpeg, JpegPluginVTable)
25
 
 
26
 
static bool
27
 
rgbToBGRA (const JSAMPLE *source,
28
 
           void          *&data,
29
 
           CompSize      &size,
30
 
           int           alpha)
31
 
{
32
 
    int  h, w;
33
 
    char *dest;
34
 
    int  height = size.height ();
35
 
    int  width = size.width ();
36
 
 
37
 
    dest = (char *) malloc ((unsigned)(height * width * 4));
38
 
    if (!dest)
39
 
        return false;
40
 
 
41
 
    data = dest;
42
 
 
43
 
    for (h = 0; h < height; h++)
44
 
        for (w = 0; w < width; w++)
45
 
        {
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;
52
 
#else
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;
57
 
#endif
58
 
        }
59
 
 
60
 
    return true;
61
 
}
62
 
 
63
 
static bool
64
 
rgbaToRGB (unsigned char *source,
65
 
           JSAMPLE       **dest,
66
 
           CompSize      &size,
67
 
           int           stride)
68
 
{
69
 
    int     h, w;
70
 
    int     height = size.height ();
71
 
    int     width = size.width ();
72
 
    int     ps = stride / width;        /* pixel size */
73
 
    JSAMPLE *d;
74
 
 
75
 
    d = (JSAMPLE *) malloc ((unsigned)height * (unsigned)width * 3 *
76
 
                            sizeof (JSAMPLE));
77
 
    if (!d)
78
 
        return false;
79
 
 
80
 
    *dest = d;
81
 
 
82
 
    for (h = 0; h < height; h++)
83
 
        for (w = 0; w < width; w++)
84
 
        {
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 */
90
 
#else
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 */
94
 
#endif
95
 
        }
96
 
 
97
 
    return true;
98
 
}
99
 
 
100
 
static void
101
 
jpegErrorExit (j_common_ptr cinfo)
102
 
{
103
 
    char                buffer[JMSG_LENGTH_MAX];
104
 
    struct jpegErrorMgr *err = (struct jpegErrorMgr *) cinfo->err;
105
 
 
106
 
    /* Format the message */
107
 
    (*cinfo->err->format_message) (cinfo, buffer);
108
 
 
109
 
    printf ("%s\n", buffer);
110
 
 
111
 
    /* Return control to the setjmp point */
112
 
    longjmp (err->setjmp_buffer, 1);
113
 
}
114
 
 
115
 
bool
116
 
JpegScreen::readJPEG (FILE     *file,
117
 
                      CompSize &size,
118
 
                      void     *&data)
119
 
{
120
 
    struct jpeg_decompress_struct cinfo;
121
 
    struct jpegErrorMgr           jerr;
122
 
    JSAMPLE                       *buf;
123
 
    JSAMPROW                      *rows;
124
 
    bool                          result;
125
 
 
126
 
    if (!file)
127
 
        return false;
128
 
 
129
 
    cinfo.err = jpeg_std_error (&jerr.pub);
130
 
    jerr.pub.error_exit = jpegErrorExit;
131
 
 
132
 
    if (setjmp (jerr.setjmp_buffer))
133
 
    {
134
 
        /* this is called on decompression errors */
135
 
        jpeg_destroy_decompress (&cinfo);
136
 
        return false;
137
 
    }
138
 
 
139
 
    jpeg_create_decompress (&cinfo);
140
 
 
141
 
    jpeg_stdio_src (&cinfo, file);
142
 
 
143
 
    jpeg_read_header (&cinfo, true);
144
 
 
145
 
    cinfo.out_color_space = JCS_RGB;
146
 
 
147
 
    jpeg_start_decompress (&cinfo);
148
 
 
149
 
    size.setHeight ((int)cinfo.output_height);
150
 
    size.setWidth ((int)cinfo.output_width);
151
 
 
152
 
    buf = (JSAMPLE *) calloc (cinfo.output_height * cinfo.output_width *
153
 
                              (unsigned)cinfo.output_components,
154
 
                              sizeof (JSAMPLE));
155
 
    if (!buf)
156
 
    {
157
 
        jpeg_finish_decompress (&cinfo);
158
 
        jpeg_destroy_decompress (&cinfo);
159
 
        return false;
160
 
    }
161
 
 
162
 
    rows = (JSAMPROW *) malloc (cinfo.output_height * sizeof (JSAMPROW));
163
 
    if (!rows)
164
 
    {
165
 
        free (buf);
166
 
        jpeg_finish_decompress (&cinfo);
167
 
        jpeg_destroy_decompress (&cinfo);
168
 
        return false;
169
 
    }
170
 
 
171
 
    for (unsigned int i = 0; i < cinfo.output_height; i++)
172
 
        rows[i] = &buf[i * cinfo.output_width *
173
 
                       (unsigned)cinfo.output_components];
174
 
 
175
 
    while (cinfo.output_scanline < cinfo.output_height)
176
 
        jpeg_read_scanlines (&cinfo, &rows[cinfo.output_scanline],
177
 
                             cinfo.output_height - cinfo.output_scanline);
178
 
 
179
 
    jpeg_finish_decompress (&cinfo);
180
 
    jpeg_destroy_decompress (&cinfo);
181
 
 
182
 
    /* convert the rgb data into BGRA format */
183
 
    result = rgbToBGRA (buf, data, size, 255);
184
 
 
185
 
    free (rows);
186
 
    free (buf);
187
 
    return result;
188
 
}
189
 
 
190
 
bool
191
 
JpegScreen::writeJPEG (unsigned char *buffer,
192
 
                       FILE          *file,
193
 
                       CompSize      &size,
194
 
                       int           stride)
195
 
{
196
 
    struct jpeg_compress_struct cinfo;
197
 
    struct jpeg_error_mgr       jerr;
198
 
    JSAMPROW                    row_pointer[1];
199
 
    JSAMPLE                     *data;
200
 
 
201
 
    /* convert the rgb data into BGRA format */
202
 
    if (!rgbaToRGB (buffer, &data, size, stride))
203
 
        return false;
204
 
 
205
 
    cinfo.err = jpeg_std_error (&jerr);
206
 
    jpeg_create_compress (&cinfo);
207
 
 
208
 
    jpeg_stdio_dest (&cinfo, file);
209
 
 
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;
214
 
 
215
 
    jpeg_set_defaults (&cinfo);
216
 
    jpeg_set_quality (&cinfo, optionGetQuality (), true);
217
 
    jpeg_start_compress (&cinfo, true);
218
 
 
219
 
    while (cinfo.next_scanline < cinfo.image_height)
220
 
    {
221
 
        row_pointer[0] =
222
 
            &data[(cinfo.image_height - cinfo.next_scanline - 1) *
223
 
                  (unsigned) size.width () * 3];
224
 
        jpeg_write_scanlines (&cinfo, row_pointer, 1);
225
 
    }
226
 
 
227
 
    jpeg_finish_compress (&cinfo);
228
 
    jpeg_destroy_compress (&cinfo);
229
 
 
230
 
    free (data);
231
 
 
232
 
    return true;
233
 
}
234
 
 
235
 
CompString
236
 
JpegScreen::fileNameWithExtension (CompString &path)
237
 
{
238
 
    unsigned int len = path.length ();
239
 
 
240
 
    if ((len > 5 && path.substr (len - 5, 5) == ".jpeg") ||
241
 
        (len > 4 && path.substr (len - 4, 4) == ".jpg"))
242
 
        return path;
243
 
 
244
 
    return path + ".jpeg";
245
 
}
246
 
 
247
 
bool
248
 
JpegScreen::imageToFile (CompString &path,
249
 
                         CompString &format,
250
 
                         CompSize   &size,
251
 
                         int       stride,
252
 
                         void      *data)
253
 
{
254
 
    bool       status = false;
255
 
    FILE       *file;
256
 
    CompString fileName = fileNameWithExtension (path);
257
 
 
258
 
    if (format == "jpeg" || format == "jpg" ||
259
 
        !(status = screen->imageToFile (path, format, size, stride, data)))
260
 
    {
261
 
        file = fopen (fileName.c_str (), "wb");
262
 
        if (file)
263
 
        {
264
 
            status = writeJPEG ((unsigned char *) data, file, size, stride);
265
 
            fclose (file);
266
 
        }
267
 
    }
268
 
 
269
 
    return status;
270
 
}
271
 
 
272
 
bool
273
 
JpegScreen::fileToImage (CompString &name,
274
 
                         CompSize   &size,
275
 
                         int        &stride,
276
 
                         void       *&data)
277
 
{
278
 
    bool       status = false;
279
 
    FILE       *file;
280
 
    CompString fileName = fileNameWithExtension (name);
281
 
 
282
 
    file = fopen (fileName.c_str (), "rb");
283
 
    if (file)
284
 
    {
285
 
        status = readJPEG (file, size, data);
286
 
        fclose (file);
287
 
    }
288
 
 
289
 
    if (status)
290
 
    {
291
 
        stride = size.width () * 4;
292
 
        return true;
293
 
    }
294
 
 
295
 
    /* Isn't a JPEG - pass to the next in the chain. */
296
 
    return screen->fileToImage (name, size, stride, data);
297
 
}
298
 
 
299
 
JpegScreen::JpegScreen (CompScreen *screen) :
300
 
    PluginClassHandler<JpegScreen, CompScreen> (screen)
301
 
{
302
 
    ScreenInterface::setHandler (screen, true);
303
 
}
304
 
 
305
 
bool
306
 
JpegPluginVTable::init ()
307
 
{
308
 
    if (!CompPlugin::checkPluginABI ("core", CORE_ABIVERSION))
309
 
        return false;
310
 
 
311
 
    return true;
312
 
}
313