~ubuntu-branches/ubuntu/jaunty/xvidcap/jaunty-proposed

« back to all changes in this revision

Viewing changes to src/xtojpg.c

  • Committer: Bazaar Package Importer
  • Author(s): John Dong
  • Date: 2008-02-25 15:47:12 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20080225154712-qvr11ekcea4c9ry8
Tags: 1.1.6-0.1ubuntu1
* Merge from debian-multimedia (LP: #120003), Ubuntu Changes:
 - For ffmpeg-related build-deps, remove cvs from package names.
 - Standards-Version 3.7.3
 - Maintainer Spec

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * xtojpg.c,
3
 
 *
4
 
 * Copyright (C) 1997,98 Rasca, Berlin
5
 
 *
6
 
 * This program is free software; you can redistribute it and/or modify
7
 
 * it under the terms of the GNU General Public License as published by
8
 
 * the Free Software Foundation; either version 2 of the License, or
9
 
 * (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., 675 Mass Ave, Cambridge, MA 02139, USA.
19
 
 */
20
 
 
21
 
#include "../config.h"  /* autoconf output */
22
 
 
23
 
#ifdef HAVE_LIBJPEG
24
 
#include <stdio.h>
25
 
#include <stdlib.h>
26
 
#include <limits.h>
27
 
#include <X11/Intrinsic.h>
28
 
#include <X11/StringDefs.h>
29
 
#include <X11/XWDFile.h>
30
 
#include "job.h"
31
 
#include "xtojpg.h"
32
 
#include "colors.h"
33
 
#include "main.h"
34
 
#include "jpeglib.h"
35
 
 
36
 
typedef struct {
37
 
        unsigned char red;
38
 
        unsigned char green;
39
 
        unsigned char blue;
40
 
} rgb;
41
 
 
42
 
 
43
 
/* global */
44
 
static unsigned char *jpg_image = NULL;
45
 
static JSAMPROW *row_pointer = NULL;
46
 
static int job_active = 0;
47
 
static struct jpeg_compress_struct cjpeg;
48
 
 
49
 
 
50
 
/*
51
 
 */
52
 
void *
53
 
JPGcolorTable (XColor *colors, int ncolors)
54
 
{
55
 
        rgb *color_tab;
56
 
        int i;
57
 
 
58
 
        color_tab = (rgb *) malloc (ncolors * sizeof (rgb));
59
 
        if (!color_tab)
60
 
                return (NULL);
61
 
        for (i =0; i < ncolors; i++) {
62
 
                color_tab[i].red = colors[i].red;
63
 
                color_tab[i].green = colors[i].green;
64
 
                color_tab[i].blue = colors[i].blue;
65
 
        }
66
 
        return (color_tab);
67
 
}
68
 
 
69
 
/*
70
 
 * for TrueColor and DirectColor
71
 
 * write a jpeg out to the named file
72
 
 */
73
 
void
74
 
XImageToJPGC (FILE *fp, XImage *image, Job *job)
75
 
{
76
 
        static struct jpeg_error_mgr jerr;
77
 
        static ColorInfo c_info;
78
 
        static unsigned long max_val;
79
 
        unsigned char *line_ptr, *p8, *p24;
80
 
        unsigned short *p16;
81
 
        int row, col;
82
 
 
83
 
        if ( job->state & VC_START ) {
84
 
                /* it's the first call, prepare the header and some statics
85
 
                 */
86
 
#ifdef DEBUG
87
 
                dump_ximage_info (image);
88
 
#endif
89
 
                /* get all the masks and max vals .. */
90
 
                GetColorInfo (image, &c_info);
91
 
                max_val = 255;
92
 
 
93
 
                jpeg_create_compress (&cjpeg);
94
 
                job_active = 1;
95
 
                cjpeg.image_width = image->width;
96
 
                cjpeg.image_height= image->height;
97
 
                cjpeg.err = jpeg_std_error (&jerr);
98
 
                cjpeg.input_components = 3;
99
 
                cjpeg.in_color_space = JCS_RGB;
100
 
                jpeg_set_defaults (&cjpeg);
101
 
                cjpeg.dct_method = JDCT_FASTEST;
102
 
                jpeg_set_quality (&cjpeg, job->quality, TRUE);
103
 
 
104
 
                /* we need an area for the jpeg image
105
 
                 */
106
 
                jpg_image = (unsigned char *) malloc (image->width * image->height * 3);
107
 
                row_pointer = (JSAMPROW *) malloc (sizeof(void*) * image->height);
108
 
        }
109
 
        jpeg_stdio_dest (&cjpeg, fp);
110
 
        jpeg_start_compress (&cjpeg, TRUE);
111
 
 
112
 
        /* for ZPixmap bits_per_pixel could be 1,4,8,16,24,32
113
 
         * but for Direct- and TrueColor it could only be 8,16,24,32 (?)
114
 
         */
115
 
        switch (image->bits_per_pixel) {
116
 
                case 8:
117
 
                        /* for 8bpp x server
118
 
                         */
119
 
                        p8 = (unsigned char *) image->data;
120
 
                        line_ptr = jpg_image;
121
 
                        for (row = 0; row < image->height; row++) {
122
 
                                row_pointer[row] = jpg_image+(row * image->width * 3);
123
 
                                for (col = 0; col < image->width; col++) {
124
 
                                        *line_ptr++ =
125
 
                                                        ((*p8 & image->red_mask) >> c_info.red_shift)
126
 
                                                        * max_val / c_info.red_max_val;
127
 
                                        *line_ptr++ =
128
 
                                                        ((*p8 & image->green_mask) >> c_info.green_shift)
129
 
                                                        * max_val / c_info.green_max_val;
130
 
                                        *line_ptr++ =
131
 
                                                        ((*p8 & image->blue_mask) >> c_info.blue_shift)
132
 
                                                        * max_val / c_info.blue_max_val;
133
 
                                        p8++;
134
 
                                }
135
 
                                /* eat paded bytes .. */
136
 
                                p8 += image->bytes_per_line -
137
 
                                                        image->bits_per_pixel / 8 * image->width;
138
 
                        }
139
 
                        break;
140
 
 
141
 
                case 16: {
142
 
                        /* for 16bpp and 15bpp x server
143
 
                         *
144
 
                         * there is no need for exact calculation, so
145
 
                         * we do some approximations to speed up ..
146
 
                         */
147
 
                        register unsigned long r_shift1, r_shift2, g_shift1, g_shift2,
148
 
                                        b_shift1, b_shift2, left_shift;
149
 
                        r_shift1 = c_info.red_bit_depth;
150
 
                        r_shift2 = c_info.red_bit_depth * 2;
151
 
                        g_shift1 = c_info.green_bit_depth;
152
 
                        g_shift2 = c_info.green_bit_depth * 2;
153
 
                        b_shift1 = c_info.blue_bit_depth;
154
 
                        b_shift2 = c_info.blue_bit_depth * 2;
155
 
                        left_shift=8; /* we expand to 24bit */
156
 
                        p16 = (unsigned short *) image->data;
157
 
                        line_ptr = jpg_image;
158
 
 
159
 
                        for (row = 0; row < image->height; row++) {
160
 
                                row_pointer[row] = jpg_image+(row * image->width * 3);
161
 
                                for (col = 0; col < image->width; col++, p16++) {
162
 
                                        *line_ptr = (*p16 & image->red_mask) >> c_info.red_shift;
163
 
                                        if (*line_ptr > 0)
164
 
                                        *line_ptr = (((*line_ptr << left_shift)-1) >> r_shift1) +
165
 
                                                                (((*line_ptr++<<left_shift)-1) >> r_shift2);
166
 
                                        else line_ptr++;
167
 
 
168
 
                                        *line_ptr = (*p16 & image->green_mask) >>c_info.green_shift;
169
 
                                        if (*line_ptr > 0)
170
 
                                        *line_ptr = (((*line_ptr << left_shift)-1) >> g_shift1) +
171
 
                                                                (((*line_ptr++<<left_shift)-1) >> g_shift2);
172
 
                                        else line_ptr++;
173
 
 
174
 
                                        *line_ptr = (*p16 & image->blue_mask) >> c_info.blue_shift;
175
 
                                        if (*line_ptr > 0)
176
 
                                        *line_ptr = (((*line_ptr << left_shift)-1) >> b_shift1) +
177
 
                                                                (((*line_ptr++<<left_shift)-1) >> b_shift2);
178
 
                                        else line_ptr++;
179
 
                                }
180
 
                                /* eat paded bytes .. we have to devide by 2 because
181
 
                                 * the p16 pointer is unsigned short *
182
 
                                 */
183
 
                                p16 += (image->bytes_per_line -
184
 
                                                (image->bits_per_pixel >> 3) * image->width) >> 1;
185
 
                        }
186
 
                        }
187
 
                        break;
188
 
 
189
 
                case 24:
190
 
                        if (image->byte_order == LSBFirst) {
191
 
                                p24 = (unsigned char *) image->data;
192
 
                                line_ptr = jpg_image;
193
 
                                for (row = 0; row < image->height; row++) {
194
 
                                        row_pointer[row] = jpg_image+(row * image->width * 3);
195
 
                                        for (col = 0; col < image->width; col++) {
196
 
                                                /* we have to swap */
197
 
                                                *line_ptr++ = p24[2];
198
 
                                                *line_ptr++ = p24[1];
199
 
                                                *line_ptr++ = p24[0];
200
 
                                                p24 += 3;
201
 
                                        }
202
 
                                        /* eat paded bytes .. */
203
 
                                        p24 += image->bytes_per_line -
204
 
                                                        (image->bits_per_pixel >> 3) * image->width;
205
 
                                }
206
 
                        } else {
207
 
                                for (row = 0; row < image->height; row++) {
208
 
                                        row_pointer[row] = image->data+(row * image->width * 3);
209
 
                                }
210
 
                        }
211
 
                        break;
212
 
 
213
 
                case 32: {
214
 
                        register unsigned long rm = image->red_mask,
215
 
                                                gm = image->green_mask,
216
 
                                                bm = image->blue_mask,
217
 
                                                r_shift = c_info.red_shift,
218
 
                                                g_shift = c_info.green_shift,
219
 
                                                b_shift = c_info.blue_shift,
220
 
                                                *p32 = (unsigned long *) image->data;
221
 
 
222
 
                        line_ptr = jpg_image;
223
 
 
224
 
                        for (row = 0; row < image->height; row++) {
225
 
                                row_pointer[row] = jpg_image+(row * image->width * 3);
226
 
 
227
 
                                for (col = 0; col < image->width; col++, p32++) {
228
 
                                        *line_ptr++ = (*p32 & rm) >> r_shift;
229
 
                                        *line_ptr++ = (*p32 & gm) >> g_shift;
230
 
                                        *line_ptr++ = (*p32 & bm) >> b_shift;
231
 
                                }
232
 
                                p32 += (image->bytes_per_line -
233
 
                                                (image->bits_per_pixel >> 3) * image->width) >> 2;
234
 
                        }
235
 
                        }
236
 
                        break;
237
 
 
238
 
                default:
239
 
                        printf ("bits_per_pixel not supported: %d\n",image->bits_per_pixel);
240
 
                        break;
241
 
        }
242
 
        /* write out the image
243
 
         */
244
 
        jpeg_write_scanlines (&cjpeg, row_pointer, image->height);
245
 
        jpeg_finish_compress (&cjpeg);
246
 
}
247
 
 
248
 
/*
249
 
 * for PseudoColor/8bpp
250
 
 * write a JPEG out to the named file, created by a palette
251
 
 */
252
 
void
253
 
XImageToJPG8 (FILE *fp, XImage *image, Job *job)
254
 
{
255
 
        static struct jpeg_error_mgr jerr;
256
 
        register unsigned char *line_ptr, *col_ptr;
257
 
        register int row, col;
258
 
 
259
 
        if ( job->state & VC_START ) {
260
 
#ifdef DEBUG
261
 
                dump_ximage_info (image);
262
 
#endif
263
 
                jpg_image = (unsigned char *) malloc (image->width * image->height * 3);
264
 
                row_pointer = (JSAMPROW *) malloc (sizeof(void*) * image->height);
265
 
 
266
 
                jpeg_create_compress (&cjpeg);
267
 
                job_active = TRUE;
268
 
 
269
 
                cjpeg.image_width = image->width;
270
 
                cjpeg.image_height= image->height;
271
 
                cjpeg.err = jpeg_std_error (&jerr);
272
 
                cjpeg.input_components = 3;
273
 
                cjpeg.in_color_space = JCS_RGB;
274
 
                jpeg_set_defaults (&cjpeg);
275
 
                if (job->quality != 75)
276
 
                        jpeg_set_quality (&cjpeg, job->quality, TRUE);
277
 
        }
278
 
        jpeg_stdio_dest (&cjpeg, fp);
279
 
        jpeg_start_compress (&cjpeg, TRUE);
280
 
 
281
 
        switch (image->bits_per_pixel) {
282
 
                case 8:
283
 
                        line_ptr = jpg_image;
284
 
                        for (row = 0; row < image->height; row++) {
285
 
                                col_ptr = image->data + (row * image->bytes_per_line);
286
 
                                row_pointer[row] = jpg_image+(row * image->width * 3);
287
 
                                for (col = 0; col < image->width; col++) {
288
 
                                        *line_ptr++ = ((rgb*)job->color_table)[*col_ptr].red;
289
 
                                        *line_ptr++ = ((rgb*)job->color_table)[*col_ptr].green;
290
 
                                        *line_ptr++ = ((rgb*)job->color_table)[*col_ptr].blue;
291
 
                                        col_ptr++;
292
 
                                }
293
 
                        }
294
 
                        jpeg_write_scanlines (&cjpeg, row_pointer, image->height);
295
 
                        jpeg_finish_compress (&cjpeg);
296
 
                        break;
297
 
                default:
298
 
                        printf ("Visual not supported!\n");
299
 
                        break;
300
 
        }
301
 
}
302
 
 
303
 
/*
304
 
 * for GrayScale and StaticGray images
305
 
 * GrayScale seems not to work :(
306
 
 */
307
 
void
308
 
XImageToJPGG (FILE *fp, XImage *image, Job *job)
309
 
{
310
 
        static struct jpeg_error_mgr jerr;
311
 
        register int row, pad;
312
 
 
313
 
        if ( job->state & VC_START ) {
314
 
#ifdef DEBUG
315
 
                dump_ximage_info (image);
316
 
#endif
317
 
                row_pointer = (JSAMPROW *) malloc (sizeof(void*) * image->height);
318
 
 
319
 
                jpeg_create_compress (&cjpeg);
320
 
                job_active = TRUE;
321
 
 
322
 
                cjpeg.image_width = image->width;
323
 
                cjpeg.image_height= image->height;
324
 
                cjpeg.err = jpeg_std_error (&jerr);
325
 
                cjpeg.input_components = 1;
326
 
                cjpeg.in_color_space = JCS_GRAYSCALE;
327
 
                jpeg_set_defaults (&cjpeg);
328
 
                if (job->quality != 75)
329
 
                        jpeg_set_quality (&cjpeg, job->quality, TRUE);
330
 
        }
331
 
        jpeg_stdio_dest (&cjpeg, fp);
332
 
        jpeg_start_compress (&cjpeg, TRUE);
333
 
 
334
 
        switch (image->bits_per_pixel) {
335
 
                case 8:
336
 
                        for (row = 0; row < image->height; row++) {
337
 
                                pad = image->bytes_per_line - image->width;
338
 
                                row_pointer[row] = image->data+(row * (image->width+pad));
339
 
                        }
340
 
                        jpeg_write_scanlines (&cjpeg, row_pointer, image->height);
341
 
                        jpeg_finish_compress (&cjpeg);
342
 
                        break;
343
 
                default:
344
 
                        printf ("Visual not supported!\n");
345
 
                        break;
346
 
        }
347
 
}
348
 
 
349
 
/*
350
 
 * clean up some previous allocated areas
351
 
 */
352
 
void
353
 
JpgClean (Job *job)
354
 
{
355
 
        if (job_active != TRUE)
356
 
                return;
357
 
        if (jpg_image) {
358
 
                free (jpg_image);
359
 
                jpg_image = NULL;
360
 
        }
361
 
        if (row_pointer) {
362
 
                free (row_pointer);
363
 
                row_pointer = NULL;
364
 
        }
365
 
        jpeg_destroy_compress (&cjpeg);
366
 
        job_active = 0;
367
 
}
368
 
#endif
369