4
* Copyright (C) 1997,98 Rasca, Berlin
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.
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., 675 Mass Ave, Cambridge, MA 02139, USA.
21
#include "../config.h" /* autoconf output */
27
#include <X11/Intrinsic.h>
28
#include <X11/StringDefs.h>
29
#include <X11/XWDFile.h>
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;
53
JPGcolorTable (XColor *colors, int ncolors)
58
color_tab = (rgb *) malloc (ncolors * sizeof (rgb));
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;
70
* for TrueColor and DirectColor
71
* write a jpeg out to the named file
74
XImageToJPGC (FILE *fp, XImage *image, Job *job)
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;
83
if ( job->state & VC_START ) {
84
/* it's the first call, prepare the header and some statics
87
dump_ximage_info (image);
89
/* get all the masks and max vals .. */
90
GetColorInfo (image, &c_info);
93
jpeg_create_compress (&cjpeg);
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);
104
/* we need an area for the jpeg image
106
jpg_image = (unsigned char *) malloc (image->width * image->height * 3);
107
row_pointer = (JSAMPROW *) malloc (sizeof(void*) * image->height);
109
jpeg_stdio_dest (&cjpeg, fp);
110
jpeg_start_compress (&cjpeg, TRUE);
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 (?)
115
switch (image->bits_per_pixel) {
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++) {
125
((*p8 & image->red_mask) >> c_info.red_shift)
126
* max_val / c_info.red_max_val;
128
((*p8 & image->green_mask) >> c_info.green_shift)
129
* max_val / c_info.green_max_val;
131
((*p8 & image->blue_mask) >> c_info.blue_shift)
132
* max_val / c_info.blue_max_val;
135
/* eat paded bytes .. */
136
p8 += image->bytes_per_line -
137
image->bits_per_pixel / 8 * image->width;
142
/* for 16bpp and 15bpp x server
144
* there is no need for exact calculation, so
145
* we do some approximations to speed up ..
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;
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;
164
*line_ptr = (((*line_ptr << left_shift)-1) >> r_shift1) +
165
(((*line_ptr++<<left_shift)-1) >> r_shift2);
168
*line_ptr = (*p16 & image->green_mask) >>c_info.green_shift;
170
*line_ptr = (((*line_ptr << left_shift)-1) >> g_shift1) +
171
(((*line_ptr++<<left_shift)-1) >> g_shift2);
174
*line_ptr = (*p16 & image->blue_mask) >> c_info.blue_shift;
176
*line_ptr = (((*line_ptr << left_shift)-1) >> b_shift1) +
177
(((*line_ptr++<<left_shift)-1) >> b_shift2);
180
/* eat paded bytes .. we have to devide by 2 because
181
* the p16 pointer is unsigned short *
183
p16 += (image->bytes_per_line -
184
(image->bits_per_pixel >> 3) * image->width) >> 1;
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];
202
/* eat paded bytes .. */
203
p24 += image->bytes_per_line -
204
(image->bits_per_pixel >> 3) * image->width;
207
for (row = 0; row < image->height; row++) {
208
row_pointer[row] = image->data+(row * image->width * 3);
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;
222
line_ptr = jpg_image;
224
for (row = 0; row < image->height; row++) {
225
row_pointer[row] = jpg_image+(row * image->width * 3);
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;
232
p32 += (image->bytes_per_line -
233
(image->bits_per_pixel >> 3) * image->width) >> 2;
239
printf ("bits_per_pixel not supported: %d\n",image->bits_per_pixel);
242
/* write out the image
244
jpeg_write_scanlines (&cjpeg, row_pointer, image->height);
245
jpeg_finish_compress (&cjpeg);
249
* for PseudoColor/8bpp
250
* write a JPEG out to the named file, created by a palette
253
XImageToJPG8 (FILE *fp, XImage *image, Job *job)
255
static struct jpeg_error_mgr jerr;
256
register unsigned char *line_ptr, *col_ptr;
257
register int row, col;
259
if ( job->state & VC_START ) {
261
dump_ximage_info (image);
263
jpg_image = (unsigned char *) malloc (image->width * image->height * 3);
264
row_pointer = (JSAMPROW *) malloc (sizeof(void*) * image->height);
266
jpeg_create_compress (&cjpeg);
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);
278
jpeg_stdio_dest (&cjpeg, fp);
279
jpeg_start_compress (&cjpeg, TRUE);
281
switch (image->bits_per_pixel) {
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;
294
jpeg_write_scanlines (&cjpeg, row_pointer, image->height);
295
jpeg_finish_compress (&cjpeg);
298
printf ("Visual not supported!\n");
304
* for GrayScale and StaticGray images
305
* GrayScale seems not to work :(
308
XImageToJPGG (FILE *fp, XImage *image, Job *job)
310
static struct jpeg_error_mgr jerr;
311
register int row, pad;
313
if ( job->state & VC_START ) {
315
dump_ximage_info (image);
317
row_pointer = (JSAMPROW *) malloc (sizeof(void*) * image->height);
319
jpeg_create_compress (&cjpeg);
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);
331
jpeg_stdio_dest (&cjpeg, fp);
332
jpeg_start_compress (&cjpeg, TRUE);
334
switch (image->bits_per_pixel) {
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));
340
jpeg_write_scanlines (&cjpeg, row_pointer, image->height);
341
jpeg_finish_compress (&cjpeg);
344
printf ("Visual not supported!\n");
350
* clean up some previous allocated areas
355
if (job_active != TRUE)
365
jpeg_destroy_compress (&cjpeg);