~profzoom/ubuntu/quantal/wmaker/bug-1079925

« back to all changes in this revision

Viewing changes to util/directjpeg.c

  • Committer: Bazaar Package Importer
  • Author(s): Marcelo E. Magallon
  • Date: 2004-11-10 14:05:30 UTC
  • Revision ID: james.westby@ubuntu.com-20041110140530-qpd66b5lm38x7apk
Tags: upstream-0.91.0
ImportĀ upstreamĀ versionĀ 0.91.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* directjpeg.c- loads a jpeg file directly into a XImage
 
2
 *
 
3
 *  WindowMaker window manager
 
4
 *
 
5
 *  Copyright (c) 1999-2003 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.
 
11
 *
 
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.
 
16
 *
 
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.
 
21
 */
 
22
 
 
23
 
 
24
#include "../src/config.h"
 
25
 
 
26
 
 
27
 
 
28
#ifdef USE_JPEG
 
29
 
 
30
#include <stdlib.h>
 
31
#include <stdio.h>
 
32
#include <string.h>
 
33
 
 
34
#include <jpeglib.h>
 
35
 
 
36
#include "../wrlib/wraster.h"
 
37
 
 
38
#include <setjmp.h>
 
39
 
 
40
 
 
41
struct my_error_mgr {
 
42
    struct jpeg_error_mgr pub;  /* "public" fields */
 
43
 
 
44
    jmp_buf setjmp_buffer;      /* for return to caller */
 
45
};
 
46
 
 
47
typedef struct my_error_mgr * my_error_ptr;
 
48
 
 
49
/*
 
50
 * Here's the routine that will replace the standard error_exit method:
 
51
 */
 
52
 
 
53
static void
 
54
my_error_exit (j_common_ptr cinfo)
 
55
{
 
56
    /* cinfo->err really points to a my_error_mgr struct, so coerce pointer */
 
57
    my_error_ptr myerr = (my_error_ptr) cinfo->err;
 
58
 
 
59
    /* Always display the message. */
 
60
    /* We could postpone this until after returning, if we chose. */
 
61
    (*cinfo->err->output_message) (cinfo);
 
62
 
 
63
    /* Return control to the setjmp point */
 
64
    longjmp(myerr->setjmp_buffer, 1);
 
65
}
 
66
 
 
67
 
 
68
static Bool
 
69
canLoad(RContext *rc)
 
70
{
 
71
    if (rc->depth != 16 || rc->vclass != TrueColor
 
72
        || rc->red_offset!=11 || rc->green_offset!=5 || rc->blue_offset!=0)
 
73
        return False;
 
74
 
 
75
    return True;
 
76
}
 
77
 
 
78
 
 
79
static void
 
80
readData(RContext *rc, struct jpeg_decompress_struct *cinfo,
 
81
         JSAMPROW *buffer, RXImage *ximg)
 
82
{
 
83
    int i, j;
 
84
    unsigned long pixel;
 
85
    int y = 0;
 
86
 
 
87
    /* for 16bpp only */
 
88
    while (cinfo->output_scanline < cinfo->output_height) {
 
89
 
 
90
        jpeg_read_scanlines(cinfo, buffer, (JDIMENSION)1);
 
91
 
 
92
        if (cinfo->out_color_space==JCS_RGB) {
 
93
            for (i=0,j=0; i<cinfo->image_width; i++) {
 
94
 
 
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);
 
99
 
 
100
                pixel = (((unsigned long)buffer[0][j++])&0xf8)<<8
 
101
                    |(((unsigned long)buffer[0][j++])&0xf4)<<3
 
102
                    |(((unsigned long)buffer[0][j++]))>>3;
 
103
 
 
104
                XPutPixel(ximg->image, i, y, pixel);
 
105
            }
 
106
        } else {
 
107
            for (i=0,j=0; i<cinfo->image_width; i++, j++) {
 
108
 
 
109
                pixel = (unsigned long)buffer[0][j]<<8
 
110
                    |(unsigned long)buffer[0][j]<<3
 
111
                    |(unsigned long)buffer[0][j]>>3;
 
112
 
 
113
                XPutPixel(ximg->image, i, y, pixel);
 
114
            }
 
115
        }
 
116
        y++;
 
117
    }
 
118
}
 
119
 
 
120
 
 
121
 
 
122
Pixmap
 
123
LoadJPEG(RContext *rc, char *file_name, int *width, int *height)
 
124
{
 
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;
 
132
 
 
133
    if (!canLoad(rc))
 
134
        return None;
 
135
 
 
136
    file = fopen(file_name, "rb");
 
137
    if (!file) {
 
138
        return None;
 
139
    }
 
140
    if (fread(buf, 2, 1, file) != 1) {
 
141
        fclose(file);
 
142
        return None;
 
143
    }
 
144
    if (buf[0] != 0xff || buf[1] != 0xd8) {
 
145
        fclose(file);
 
146
        return None;
 
147
    }
 
148
    rewind(file);
 
149
 
 
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.
 
156
         */
 
157
        jpeg_destroy_decompress(&cinfo);
 
158
        fclose(file);
 
159
 
 
160
        if (ximg) {
 
161
            RDestroyXImage(rc, ximg);
 
162
        }
 
163
 
 
164
        return None;
 
165
    }
 
166
 
 
167
    jpeg_create_decompress(&cinfo);
 
168
 
 
169
    jpeg_stdio_src(&cinfo, file);
 
170
 
 
171
    jpeg_read_header(&cinfo, TRUE);
 
172
 
 
173
    buffer[0] = (JSAMPROW)malloc(cinfo.image_width*cinfo.num_components);
 
174
    if (!buffer[0]) {
 
175
        RErrorCode = RERR_NOMEMORY;
 
176
        goto bye;
 
177
    }
 
178
 
 
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);
 
187
 
 
188
    ximg = RCreateXImage(rc, rc->depth, cinfo.image_width, cinfo.image_height);
 
189
    if (!ximg) {
 
190
        goto bye;
 
191
    }
 
192
    jpeg_start_decompress(&cinfo);
 
193
 
 
194
    readData(rc, &cinfo, buffer, ximg);
 
195
 
 
196
    jpeg_finish_decompress(&cinfo);
 
197
 
 
198
    p = XCreatePixmap(rc->dpy, rc->drawable, cinfo.image_width,
 
199
                      cinfo.image_height, rc->depth);
 
200
 
 
201
    RPutXImage(rc, p, rc->copy_gc, ximg, 0, 0, 0, 0, cinfo.image_width,
 
202
               cinfo.image_height);
 
203
 
 
204
    *width = cinfo.image_width;
 
205
    *height = cinfo.image_height;
 
206
 
 
207
bye:
 
208
    jpeg_destroy_decompress(&cinfo);
 
209
 
 
210
    fclose(file);
 
211
 
 
212
    if (buffer[0])
 
213
        free(buffer[0]);
 
214
 
 
215
    if (ximg)
 
216
        RDestroyXImage(rc, ximg);
 
217
 
 
218
    return p;
 
219
}
 
220
 
 
221
#endif /* USE_JPEG */
 
222