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