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