Added a framework for testing CreateProcess and a few tests.
[wine] / dlls / quartz / ijgdec.c
1 /*
2  * A simple wrapper of JPEG decoder.
3  *
4  * Copyright (C) Hidenori TAKESHIMA <hidenori@a2.ctktv.ne.jp>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library 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 GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21
22 #include "config.h"
23
24 #include <stdio.h>
25 #include <string.h>
26 #include <stdlib.h>
27
28 #include "ijgdec.h"
29
30 #if defined(HAVE_LIBJPEG) && defined(HAVE_JPEGLIB_H)
31
32 #include <jpeglib.h>
33 #include <jerror.h>
34 #include <setjmp.h>
35
36 typedef struct IJGSrcImpl IJGSrcImpl;
37 typedef struct IJGErrImpl IJGErrImpl;
38 struct IJGSrcImpl
39 {
40         struct jpeg_source_mgr  pub;    /* must be first */
41
42         const char** ppsrcs;
43         const int* plenofsrcs;
44         int srccount;
45         int srcindex;
46 };
47
48 struct IJGErrImpl
49 {
50         struct jpeg_error_mgr err;
51
52         jmp_buf env;
53 };
54
55
56 /* for the jpeg decompressor source manager. */
57 static void IJGDec_init_source(j_decompress_ptr cinfo) {}
58
59 static boolean IJGDec_fill_input_buffer(j_decompress_ptr cinfo)
60 {
61         IJGSrcImpl* pImpl = (IJGSrcImpl*)cinfo->src;
62
63         if ( pImpl->srcindex >= pImpl->srccount )
64         {
65                 ERREXIT(cinfo, JERR_INPUT_EMPTY);
66         }
67         pImpl->pub.next_input_byte = pImpl->ppsrcs[pImpl->srcindex];
68         pImpl->pub.bytes_in_buffer = pImpl->plenofsrcs[pImpl->srcindex];
69         pImpl->srcindex ++;
70
71         return TRUE;
72 }
73
74 static void IJGDec_skip_input_data(j_decompress_ptr cinfo,long num_bytes)
75 {
76         IJGSrcImpl* pImpl = (IJGSrcImpl*)cinfo->src;
77
78         if ( num_bytes <= 0 ) return;
79
80         while ( num_bytes > pImpl->pub.bytes_in_buffer )
81         {
82                 num_bytes -= pImpl->pub.bytes_in_buffer;
83                 if ( !IJGDec_fill_input_buffer(cinfo) )
84                 {
85                         ERREXIT(cinfo, JERR_INPUT_EMPTY);
86                 }
87         }
88
89         pImpl->pub.next_input_byte += num_bytes;
90         pImpl->pub.bytes_in_buffer -= num_bytes;
91 }
92
93 static void IJGDec_term_source(j_decompress_ptr cinfo)
94 {
95 }
96
97 static void IJGDec_error_exit(j_common_ptr cinfo)
98 {
99         IJGErrImpl* pImpl = (IJGErrImpl*)cinfo->err;
100
101         longjmp(pImpl->env,1);
102 }
103
104 static void rgb_to_bgr(char* pdata,int width)
105 {
106         int x;
107         char c;
108
109         for(x=0;x<width;x++)
110         {
111                 c = pdata[0];
112                 pdata[0] = pdata[2];
113                 pdata[2] = c;
114                 pdata += 3;
115         }
116 }
117
118 int IJGDEC_Decode( char* pdst, int dstpitch, int dstwidth, int dstheight, int dstbpp, const char** ppsrcs, const int* plenofsrcs, int srccount )
119 {
120         IJGSrcImpl jsrc;
121         IJGErrImpl jerr;
122         struct jpeg_decompress_struct jdec;
123         int ret = -1;
124
125         jsrc.ppsrcs = ppsrcs;
126         jsrc.plenofsrcs = plenofsrcs;
127         jsrc.srccount = srccount;
128         jsrc.srcindex = 0;
129         jsrc.pub.bytes_in_buffer = 0;
130         jsrc.pub.next_input_byte = NULL;
131         jsrc.pub.init_source = IJGDec_init_source;
132         jsrc.pub.fill_input_buffer = IJGDec_fill_input_buffer;
133         jsrc.pub.skip_input_data = IJGDec_skip_input_data;
134         jsrc.pub.resync_to_restart = jpeg_resync_to_restart;
135         jsrc.pub.term_source = IJGDec_term_source;
136
137         jdec.err = jpeg_std_error(&jerr.err);
138         jerr.err.error_exit = IJGDec_error_exit;
139
140         if ( setjmp(jerr.env) != 0 )
141         {
142                 jpeg_destroy_decompress(&jdec);
143                 return -1;
144         }
145
146         jpeg_create_decompress(&jdec);
147         jdec.src = &jsrc;
148
149         ret = jpeg_read_header(&jdec,TRUE);
150         if ( ret != JPEG_HEADER_OK ) goto err;
151
152         jpeg_start_decompress(&jdec);
153
154         if ( jdec.output_width != dstwidth ||
155                  jdec.output_height != dstheight ||
156                  (jdec.output_components*8) != dstbpp ) goto err;
157
158         while (jdec.output_scanline < jdec.output_height)
159         {
160                 jpeg_read_scanlines(&jdec,(JSAMPLE**)&pdst,1);
161                 rgb_to_bgr(pdst,dstwidth);
162                 pdst += dstpitch;
163         }
164
165         jpeg_finish_decompress(&jdec);
166         ret = 0;
167 err:
168         jpeg_destroy_decompress(&jdec);
169
170         return ret;
171 }
172
173 #else
174
175 int IJGDEC_Decode( char* pdst, int dstpitch, int dstwidth, int dstheight, int dstbpp, const char** ppsrcs, const int* plenofsrcs, int srccount )
176 {
177         return -1;
178 }
179
180 #endif
181
182