Fix bugs in previous commit that caused FTBFS in synfig and ETL FTBFS with older...
[synfig.git] / synfig-core / tags / synfig_0_61_03 / synfig-core / src / modules / mod_jpeg / mptr_jpeg.cpp
1 /*! ========================================================================
2 ** Synfig
3 ** ppm Target Module
4 ** $Id: mptr_jpeg.cpp,v 1.1.1.1 2005/01/04 01:23:11 darco Exp $
5 **
6 **      Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
7 **
8 **      This package is free software; you can redistribute it and/or
9 **      modify it under the terms of the GNU General Public License as
10 **      published by the Free Software Foundation; either version 2 of
11 **      the License, or (at your option) any later version.
12 **
13 **      This package is distributed in the hope that it will be useful,
14 **      but WITHOUT ANY WARRANTY; without even the implied warranty of
15 **      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 **      General Public License for more details.
17 **
18 ** === N O T E S ===========================================================
19 **
20 ** ========================================================================= */
21
22 /*! \todo Support 16 bit JPEG files
23 **      \todo Support for paletted JPEG files
24 **      \todo Support GAMMA correction
25 **      \todo Fix memory leaks
26 */
27
28 /* === H E A D E R S ======================================================= */
29
30 #ifdef USING_PCH
31 #       include "pch.h"
32 #else
33 #ifdef HAVE_CONFIG_H
34 #       include <config.h>
35 #endif
36
37 #include "mptr_jpeg.h"
38 #include <synfig/importer.h>
39 #include <synfig/time.h>
40 #include <synfig/general.h>
41
42
43 #include <cstdio>
44 #include <algorithm>
45 #include <functional>
46 #endif
47
48 /* === M A C R O S ========================================================= */
49
50 using namespace synfig;
51 using namespace std;
52 using namespace etl;
53
54 #define JPEG_CHECK_BYTES        8
55
56 /* === G L O B A L S ======================================================= */
57
58 SYNFIG_IMPORTER_INIT(jpeg_mptr);
59 SYNFIG_IMPORTER_SET_NAME(jpeg_mptr,"jpeg_mptr");
60 SYNFIG_IMPORTER_SET_EXT(jpeg_mptr,"jpg");
61 SYNFIG_IMPORTER_SET_VERSION(jpeg_mptr,"0.1");
62 SYNFIG_IMPORTER_SET_CVS_ID(jpeg_mptr,"$Id: mptr_jpeg.cpp,v 1.1.1.1 2005/01/04 01:23:11 darco Exp $");
63
64 /* === M E T H O D S ======================================================= */
65
66 struct my_error_mgr {
67   struct jpeg_error_mgr pub;    /* "public" fields */
68
69   jmp_buf setjmp_buffer;        /* for return to caller */
70 };
71
72 typedef struct my_error_mgr * my_error_ptr;
73
74 /*
75  * Here's the routine that will replace the standard error_exit method:
76  */
77
78 void
79 jpeg_mptr::my_error_exit (j_common_ptr cinfo)
80 {
81   /* cinfo->err really points to a my_error_mgr struct, so coerce pointer */
82   my_error_ptr myerr = (my_error_ptr) cinfo->err;
83
84   /* Always display the message. */
85   /* We could postpone this until after returning, if we chose. */
86   (*cinfo->err->output_message) (cinfo);
87
88   /* Return control to the setjmp point */
89   longjmp(myerr->setjmp_buffer, 1);
90 }
91
92
93
94
95
96 jpeg_mptr::jpeg_mptr(const char *file_name)
97 {
98         struct my_error_mgr jerr;
99         filename=file_name;
100         
101         /* Open the file pointer */
102     FILE *file = fopen(file_name, "rb");
103     if (!file)
104     {
105         //! \todo THROW SOMETHING
106                 throw String("error on importer construction, *WRITEME*1");
107                 return;
108     }
109     
110         /* Step 1: allocate and initialize JPEG decompression object */
111         
112         /* We set up the normal JPEG error routines, then override error_exit. */
113         cinfo.err = jpeg_std_error(&jerr.pub);
114         jerr.pub.error_exit = my_error_exit;
115         /* Establish the setjmp return context for my_error_exit to use. */
116         if (setjmp(jerr.setjmp_buffer)) {
117                 /* If we get here, the JPEG code has signaled an error.
118                  * We need to clean up the JPEG object, close the input file, and return.
119                  */
120                 jpeg_destroy_decompress(&cinfo);
121                 fclose(file);
122                 throw String("error on importer construction, *WRITEME*2");
123         }
124         /* Now we can initialize the JPEG decompression object. */
125         jpeg_create_decompress(&cinfo);
126         
127         /* Step 2: specify data source (eg, a file) */
128         
129         jpeg_stdio_src(&cinfo, file);
130         
131         /* Step 3: read file parameters with jpeg_read_header() */
132         
133         (void) jpeg_read_header(&cinfo, TRUE);
134         /* We can ignore the return value from jpeg_read_header since
135         *   (a) suspension is not possible with the stdio data source, and
136         *   (b) we passed TRUE to reject a tables-only JPEG file as an error.
137         * See libjpeg.doc for more info.
138         */
139         
140         /* Step 4: set parameters for decompression */
141         
142         /* In this example, we don't need to change any of the defaults set by
143         * jpeg_read_header(), so we do nothing here.
144         */
145         
146         /* Step 5: Start decompressor */
147         
148         (void) jpeg_start_decompress(&cinfo);
149         /* We can ignore the return value since suspension is not possible
150         * with the stdio data source.
151         */
152
153         JSAMPARRAY buffer;              /* Output row buffer */
154         int row_stride;         /* physical row width in output buffer */
155         row_stride = cinfo.output_width * cinfo.output_components;
156         /* Make a one-row-high sample array that will go away when done with image */
157         buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);
158
159         if(!buffer)
160         {
161                 synfig::error("jpeg_mptr: error: alloc of \"buffer\" failed (bug?)");
162                 throw String("alloc of \"buffer\" failed (bug?)");
163         }
164                 
165         int x;
166         int y;
167         surface_buffer.set_wh(cinfo.output_width,cinfo.output_height);
168
169         switch(cinfo.output_components)
170         {
171         case 3:
172                 for(y=0;y<surface_buffer.get_h();y++)
173                 {
174                         int x;
175                         jpeg_read_scanlines(&cinfo, buffer, 1);                 
176                         for(x=0;x<surface_buffer.get_w();x++)
177                         {
178                                 float r=gamma().g_U8_to_F32((unsigned char)buffer[0][x*3+0]);
179                                 float g=gamma().g_U8_to_F32((unsigned char)buffer[0][x*3+1]);
180                                 float b=gamma().g_U8_to_F32((unsigned char)buffer[0][x*3+2]);
181                                 surface_buffer[y][x]=Color(
182                                         r,
183                                         g,
184                                         b,
185                                         1.0
186                                 );
187 /*
188                                 surface_buffer[y][x]=Color(
189                                         (float)(unsigned char)buffer[0][x*3+0]*(1.0/255.0),
190                                         (float)(unsigned char)buffer[0][x*3+1]*(1.0/255.0),
191                                         (float)(unsigned char)buffer[0][x*3+2]*(1.0/255.0),
192                                         1.0
193                                 );
194 */
195                                 }
196                 }
197                 break;
198                         
199         case 1:
200                 for(y=0;y<surface_buffer.get_h();y++)
201                 {
202                         jpeg_read_scanlines(&cinfo, buffer, 1);                 
203                         for(x=0;x<surface_buffer.get_w();x++)
204                         {
205                                 float gray=gamma().g_U8_to_F32((unsigned char)buffer[0][x]);
206 //                              float gray=(float)(unsigned char)buffer[0][x]*(1.0/255.0);
207                                 surface_buffer[y][x]=Color(
208                                         gray,
209                                         gray,
210                                         gray,
211                                         1.0
212                                 );
213                         }
214                 }
215                 break;
216
217         default:
218                 synfig::error("jpeg_mptr: error: Unsupported color type");
219         //! \todo THROW SOMETHING
220                 throw String("error on importer construction, *WRITEME*6");
221                 return;
222         }
223         
224         /* Step 7: Finish decompression */
225         
226         (void) jpeg_finish_decompress(&cinfo);
227         /* We can ignore the return value since suspension is not possible
228         * with the stdio data source.
229         */
230         
231         /* Step 8: Release JPEG decompression object */
232         
233         /* This is an important step since it will release a good deal of memory. */
234         jpeg_destroy_decompress(&cinfo);
235         
236         /* After finish_decompress, we can close the input file.
237         * Here we postpone it until after no more JPEG errors are possible,
238         * so as to simplify the setjmp error logic above.  (Actually, I don't
239         * think that jpeg_destroy can do an error exit, but why assume anything...)
240         */
241         fclose(file);
242 }
243
244 jpeg_mptr::~jpeg_mptr()
245 {
246 }
247
248 bool
249 jpeg_mptr::get_frame(synfig::Surface &surface,Time, synfig::ProgressCallback *cb)
250 {
251         surface.mirror(surface_buffer);
252         return true;
253 }