- Fixed text in info panel for multibyte (Seiichi SATO <ssato@sh.rim.or.jp>)
[wmaker-crm.git] / util / directjpeg.c
blobb91544b4e784e8a82b5b87de767c45e0ae47a888
1 /* directjpeg.c- loads a jpeg file directly into a XImage
3 * WindowMaker window manager
4 *
5 * Copyright (c) 1999-2002 Alfredo K. Kojima
6 *
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,
20 * USA.
24 #include "../src/config.h"
28 #ifdef USE_JPEG
30 #include <stdlib.h>
31 #include <stdio.h>
32 #include <string.h>
34 #include <jpeglib.h>
36 #include "../wrlib/wraster.h"
38 #include <setjmp.h>
41 struct my_error_mgr {
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:
53 static void
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);
68 static Bool
69 canLoad(RContext *rc)
71 if (rc->depth != 16 || rc->vclass != TrueColor
72 || rc->red_offset!=11 || rc->green_offset!=5 || rc->blue_offset!=0)
73 return False;
75 return True;
79 static void
80 readData(RContext *rc, struct jpeg_decompress_struct *cinfo,
81 JSAMPROW *buffer, RXImage *ximg)
83 int i, j;
84 unsigned long pixel;
85 int y = 0;
87 /* for 16bpp only */
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++) {
95 printf("%i %i %i\n",
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);
106 } else {
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);
116 y++;
122 Pixmap
123 LoadJPEG(RContext *rc, char *file_name, int *width, int *height)
125 struct jpeg_decompress_struct cinfo;
126 JSAMPROW buffer[1];
127 FILE *file;
128 struct my_error_mgr jerr;
129 RXImage *ximg = NULL;
130 unsigned char buf[8];
131 Pixmap p = None;
133 if (!canLoad(rc))
134 return None;
136 file = fopen(file_name, "r");
137 if (!file) {
138 return None;
140 if (fread(buf, 2, 1, file) != 1) {
141 fclose(file);
142 return None;
144 if (buf[0] != 0xff || buf[1] != 0xd8) {
145 fclose(file);
146 return None;
148 rewind(file);
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);
158 fclose(file);
160 if (ximg) {
161 RDestroyXImage(rc, ximg);
164 return None;
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);
174 if (!buffer[0]) {
175 RErrorCode = RERR_NOMEMORY;
176 goto bye;
179 if(cinfo.jpeg_color_space==JCS_GRAYSCALE) {
180 cinfo.out_color_space=JCS_GRAYSCALE;
181 } else
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);
189 if (!ximg) {
190 goto bye;
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,
202 cinfo.image_height);
204 *width = cinfo.image_width;
205 *height = cinfo.image_height;
207 bye:
208 jpeg_destroy_decompress(&cinfo);
210 fclose(file);
212 if (buffer[0])
213 free(buffer[0]);
215 if (ximg)
216 RDestroyXImage(rc, ximg);
218 return p;
221 #endif /* USE_JPEG */