1 /* directjpeg.c- loads a jpeg file directly into a XImage
3 * WindowMaker window manager
5 * Copyright (c) 1999 Alfredo K. Kojima
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
24 #include "../src/config.h"
36 #include "../wrlib/wraster.h"
42 struct jpeg_error_mgr pub
; /* "public" fields */
44 jmp_buf setjmp_buffer
; /* for return to caller */
47 typedef struct my_error_mgr
* my_error_ptr
;
50 * Here's the routine that will replace the standard error_exit method:
54 my_error_exit (j_common_ptr cinfo
)
56 /* cinfo->err really points to a my_error_mgr struct, so coerce pointer */
57 my_error_ptr myerr
= (my_error_ptr
) cinfo
->err
;
59 /* Always display the message. */
60 /* We could postpone this until after returning, if we chose. */
61 (*cinfo
->err
->output_message
) (cinfo
);
63 /* Return control to the setjmp point */
64 longjmp(myerr
->setjmp_buffer
, 1);
71 if (rc
->depth
!= 16 || rc
->vclass
!= TrueColor
72 || rc
->red_offset
!=11 || rc
->green_offset
!=5 || rc
->blue_offset
!=0)
80 readData(RContext
*rc
, struct jpeg_decompress_struct
*cinfo
,
81 JSAMPROW
*buffer
, RXImage
*ximg
)
88 while (cinfo
->output_scanline
< cinfo
->output_height
) {
90 jpeg_read_scanlines(cinfo
, buffer
, (JDIMENSION
)1);
92 if (cinfo
->out_color_space
==JCS_RGB
) {
93 for (i
=0,j
=0; i
<cinfo
->image_width
; i
++) {
96 (((unsigned long)buffer
[0][j
])&0xf8)<<8,
97 (((unsigned long)buffer
[0][j
+1])&0xf4)<<3,
98 (((unsigned long)buffer
[0][j
+2]))>>3);
100 pixel
= (((unsigned long)buffer
[0][j
++])&0xf8)<<8
101 |(((unsigned long)buffer
[0][j
++])&0xf4)<<3
102 |(((unsigned long)buffer
[0][j
++]))>>3;
104 XPutPixel(ximg
->image
, i
, y
, pixel
);
107 for (i
=0,j
=0; i
<cinfo
->image_width
; i
++, j
++) {
109 pixel
= (unsigned long)buffer
[0][j
]<<8
110 |(unsigned long)buffer
[0][j
]<<3
111 |(unsigned long)buffer
[0][j
]>>3;
113 XPutPixel(ximg
->image
, i
, y
, pixel
);
123 LoadJPEG(RContext
*rc
, char *file_name
, int *width
, int *height
)
125 struct jpeg_decompress_struct cinfo
;
128 struct my_error_mgr jerr
;
129 RXImage
*ximg
= NULL
;
130 unsigned char buf
[8];
136 file
= fopen(file_name
, "r");
140 if (fread(buf
, 2, 1, file
) != 1) {
144 if (buf
[0] != 0xff || buf
[1] != 0xd8) {
150 cinfo
.err
= jpeg_std_error(&jerr
.pub
);
151 jerr
.pub
.error_exit
= my_error_exit
;
152 /* Establish the setjmp return context for my_error_exit to use. */
153 if (setjmp(jerr
.setjmp_buffer
)) {
154 /* If we get here, the JPEG code has signaled an error.
155 * We need to clean up the JPEG object, close the input file, and return.
157 jpeg_destroy_decompress(&cinfo
);
161 RDestroyXImage(rc
, ximg
);
167 jpeg_create_decompress(&cinfo
);
169 jpeg_stdio_src(&cinfo
, file
);
171 jpeg_read_header(&cinfo
, TRUE
);
173 buffer
[0] = (JSAMPROW
)malloc(cinfo
.image_width
*cinfo
.num_components
);
175 RErrorCode
= RERR_NOMEMORY
;
179 if(cinfo
.jpeg_color_space
==JCS_GRAYSCALE
) {
180 cinfo
.out_color_space
=JCS_GRAYSCALE
;
182 cinfo
.out_color_space
= JCS_RGB
;
183 cinfo
.quantize_colors
= FALSE
;
184 cinfo
.do_fancy_upsampling
= FALSE
;
185 cinfo
.do_block_smoothing
= FALSE
;
186 jpeg_calc_output_dimensions(&cinfo
);
188 ximg
= RCreateXImage(rc
, rc
->depth
, cinfo
.image_width
, cinfo
.image_height
);
192 jpeg_start_decompress(&cinfo
);
194 readData(rc
, &cinfo
, buffer
, ximg
);
196 jpeg_finish_decompress(&cinfo
);
198 p
= XCreatePixmap(rc
->dpy
, rc
->drawable
, cinfo
.image_width
,
199 cinfo
.image_height
, rc
->depth
);
201 RPutXImage(rc
, p
, rc
->copy_gc
, ximg
, 0, 0, 0, 0, cinfo
.image_width
,
204 *width
= cinfo
.image_width
;
205 *height
= cinfo
.image_height
;
208 jpeg_destroy_decompress(&cinfo
);
216 RDestroyXImage(rc
, ximg
);
221 #endif /* USE_JPEG */