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