Improved success for the linux build; OPJViewer shows all the COM contents
[openjpeg.git] / OPJViewer / source / imagjp2.cpp
1 /*\r
2  * Copyright (c) 2007, Digital Signal Processing Laboratory, Universit� degli studi di Perugia (UPG), Italy\r
3  * All rights reserved.\r
4  *\r
5  * Redistribution and use in source and binary forms, with or without\r
6  * modification, are permitted provided that the following conditions\r
7  * are met:\r
8  * 1. Redistributions of source code must retain the above copyright\r
9  *    notice, this list of conditions and the following disclaimer.\r
10  * 2. Redistributions in binary form must reproduce the above copyright\r
11  *    notice, this list of conditions and the following disclaimer in the\r
12  *    documentation and/or other materials provided with the distribution.\r
13  *\r
14  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'\r
15  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\r
18  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
19  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
20  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
21  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
22  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
23  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
24  * POSSIBILITY OF SUCH DAMAGE.\r
25  */\r
26 /////////////////////////////////////////////////////////////////////////////\r
27 // Name:        imagjp2.cpp\r
28 // Purpose:     wxImage JPEG 2000 file format handler\r
29 // Author:      Giuseppe Baruffa - based on imagjpeg.cpp, Vaclav Slavik\r
30 // RCS-ID:      $Id: imagjp2.cpp,v 0.00 2007/02/08 23:59:00 MW Exp $\r
31 // Copyright:   (c) Giuseppe Baruffa\r
32 // Licence:     wxWindows licence\r
33 /////////////////////////////////////////////////////////////////////////////\r
34 \r
35 // For compilers that support precompilation, includes "wx.h".\r
36 #include "wx/wxprec.h"\r
37 \r
38 #ifdef __BORLANDC__\r
39     #pragma hdrstop\r
40 #endif\r
41 \r
42 #if wxUSE_IMAGE && wxUSE_LIBOPENJPEG\r
43 \r
44 #include "imagjp2.h"\r
45 \r
46 #ifndef WX_PRECOMP\r
47     #include "wx/log.h"\r
48     #include "wx/app.h"\r
49     #include "wx/intl.h"\r
50     #include "wx/bitmap.h"\r
51     #include "wx/module.h"\r
52 #endif\r
53 \r
54 \r
55 #include "libopenjpeg/openjpeg.h"\r
56 \r
57 \r
58 #include "wx/filefn.h"\r
59 #include "wx/wfstream.h"\r
60 \r
61 // ----------------------------------------------------------------------------\r
62 // types\r
63 // ----------------------------------------------------------------------------\r
64 \r
65 \r
66 //-----------------------------------------------------------------------------\r
67 // wxJP2Handler\r
68 //-----------------------------------------------------------------------------\r
69 \r
70 IMPLEMENT_DYNAMIC_CLASS(wxJP2Handler,wxImageHandler)\r
71 \r
72 #if wxUSE_STREAMS\r
73 \r
74 //------------- JPEG 2000 Data Source Manager\r
75 \r
76 #define J2K_CFMT 0\r
77 #define JP2_CFMT 1\r
78 #define JPT_CFMT 2\r
79 #define MJ2_CFMT 3\r
80 #define PXM_DFMT 0\r
81 #define PGX_DFMT 1\r
82 #define BMP_DFMT 2\r
83 #define YUV_DFMT 3\r
84 \r
85 #define MAX_MESSAGE_LEN 200\r
86 \r
87 /* sample error callback expecting a FILE* client object */\r
88 void jp2_error_callback(const char *msg, void *client_data) {\r
89         int message_len = strlen(msg) - 1;\r
90         if (msg[message_len] != '\n')\r
91                 message_len = MAX_MESSAGE_LEN;\r
92 #ifndef __WXGTK__ \r
93                 wxMutexGuiEnter();\r
94 #endif /* __WXGTK__ */\r
95         wxLogMessage(wxT("[ERROR] %.*s"), message_len, msg);\r
96 #ifndef __WXGTK__ \r
97     wxMutexGuiLeave();\r
98 #endif /* __WXGTK__ */\r
99 }\r
100 \r
101 /* sample warning callback expecting a FILE* client object */\r
102 void jp2_warning_callback(const char *msg, void *client_data) {\r
103         int message_len = strlen(msg) - 1;\r
104         if (msg[message_len] != '\n')\r
105                 message_len = MAX_MESSAGE_LEN;\r
106 #ifndef __WXGTK__ \r
107                 wxMutexGuiEnter();\r
108 #endif /* __WXGTK__ */\r
109         wxLogMessage(wxT("[WARNING] %.*s"), message_len, msg);\r
110 #ifndef __WXGTK__ \r
111     wxMutexGuiLeave();\r
112 #endif /* __WXGTK__ */\r
113 }\r
114 \r
115 /* sample debug callback expecting no client object */\r
116 void jp2_info_callback(const char *msg, void *client_data) {\r
117         int message_len = strlen(msg) - 1;\r
118         if (msg[message_len] != '\n')\r
119                 message_len = MAX_MESSAGE_LEN;\r
120 #ifndef __WXGTK__ \r
121                 wxMutexGuiEnter();\r
122 #endif /* __WXGTK__ */\r
123         wxLogMessage(wxT("[INFO] %.*s"), message_len, msg);\r
124 #ifndef __WXGTK__ \r
125     wxMutexGuiLeave();\r
126 #endif /* __WXGTK__ */\r
127 }\r
128 \r
129 // load the jp2 file format\r
130 bool wxJP2Handler::LoadFile(wxImage *image, wxInputStream& stream, bool verbose, int index)\r
131 {\r
132         opj_dparameters_t parameters;   /* decompression parameters */\r
133         opj_event_mgr_t event_mgr;              /* event manager */\r
134         opj_image_t *opjimage = NULL;\r
135         unsigned char *src = NULL;\r
136     unsigned char *ptr;\r
137         int file_length;\r
138         opj_codestream_info_t cstr_info;  /* Codestream information structure */\r
139 \r
140         // destroy the image\r
141     image->Destroy();\r
142 \r
143         /* handle to a decompressor */\r
144         opj_dinfo_t* dinfo = NULL;      \r
145         opj_cio_t *cio = NULL;\r
146 \r
147         /* configure the event callbacks (not required) */\r
148         memset(&event_mgr, 0, sizeof(opj_event_mgr_t));\r
149         event_mgr.error_handler = jp2_error_callback;\r
150         event_mgr.warning_handler = jp2_warning_callback;\r
151         event_mgr.info_handler = jp2_info_callback;\r
152 \r
153         /* set decoding parameters to default values */\r
154         opj_set_default_decoder_parameters(&parameters);\r
155 \r
156         /* prepare parameters */\r
157         strncpy(parameters.infile, "", sizeof(parameters.infile)-1);\r
158         strncpy(parameters.outfile, "", sizeof(parameters.outfile)-1);\r
159         parameters.decod_format = JP2_CFMT;\r
160         parameters.cod_format = BMP_DFMT;\r
161         if (m_reducefactor)\r
162                 parameters.cp_reduce = m_reducefactor;\r
163         if (m_qualitylayers)\r
164                 parameters.cp_layer = m_qualitylayers;\r
165         /*if (n_components)\r
166                 parameters. = n_components;*/\r
167 \r
168         /* JPWL only */\r
169 #ifdef USE_JPWL\r
170         parameters.jpwl_exp_comps = m_expcomps;\r
171         parameters.jpwl_max_tiles = m_maxtiles;\r
172         parameters.jpwl_correct = m_enablejpwl;\r
173 #endif /* USE_JPWL */\r
174 \r
175         /* get a decoder handle */\r
176         dinfo = opj_create_decompress(CODEC_JP2);\r
177 \r
178         /* find length of the stream */\r
179         stream.SeekI(0, wxFromEnd);\r
180         file_length = (int) stream.TellI();\r
181 \r
182         /* get data */\r
183         stream.SeekI(0, wxFromStart);\r
184     src = (unsigned char *) malloc(file_length);\r
185         stream.Read(src, file_length);\r
186 \r
187         /* catch events using our callbacks and give a local context */\r
188         opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, stderr);\r
189 \r
190         /* setup the decoder decoding parameters using user parameters */\r
191         opj_setup_decoder(dinfo, &parameters);\r
192 \r
193         /* open a byte stream */\r
194         cio = opj_cio_open((opj_common_ptr)dinfo, src, file_length);\r
195 \r
196         /* decode the stream and fill the image structure */\r
197         opjimage = opj_decode_with_info(dinfo, cio, &cstr_info);\r
198         if (!opjimage) {\r
199 #ifndef __WXGTK__ \r
200                 wxMutexGuiEnter();\r
201 #endif /* __WXGTK__ */\r
202                 wxLogError(wxT("JP2: failed to decode image!"));\r
203 #ifndef __WXGTK__ \r
204                 wxMutexGuiLeave();\r
205 #endif /* __WXGTK__ */\r
206                 opj_destroy_decompress(dinfo);\r
207                 opj_cio_close(cio);\r
208                 free(src);\r
209                 return false;\r
210         }\r
211 \r
212         /* close the byte stream */\r
213         opj_cio_close(cio);\r
214 \r
215         /* common rendering method */\r
216 #include "imagjpeg2000.cpp"\r
217 \r
218 #ifndef __WXGTK__ \r
219                 wxMutexGuiEnter();\r
220 #endif /* __WXGTK__ */\r
221     wxLogMessage(wxT("JP2: image loaded."));\r
222 #ifndef __WXGTK__ \r
223                 wxMutexGuiLeave();\r
224 #endif /* __WXGTK__ */\r
225 \r
226         /* close openjpeg structs */\r
227         opj_destroy_decompress(dinfo);\r
228         opj_image_destroy(opjimage);\r
229         free(src);\r
230 \r
231         if (!image->Ok())\r
232                 return false;\r
233         else\r
234                 return true;\r
235 \r
236 }\r
237 \r
238 // save the jp2 file format\r
239 bool wxJP2Handler::SaveFile( wxImage *image, wxOutputStream& stream, bool verbose )\r
240 {\r
241 #ifndef __WXGTK__ \r
242                 wxMutexGuiEnter();\r
243 #endif /* __WXGTK__ */\r
244     wxLogError(wxT("JP2: Couldn't save image -> not implemented."));\r
245 #ifndef __WXGTK__ \r
246                 wxMutexGuiLeave();\r
247 #endif /* __WXGTK__ */\r
248 \r
249     return false;\r
250 }\r
251 \r
252 #ifdef __VISUALC__\r
253     #pragma warning(default:4611)\r
254 #endif /* VC++ */\r
255 \r
256 // recognize the JPEG 2000 starting box\r
257 bool wxJP2Handler::DoCanRead( wxInputStream& stream )\r
258 {\r
259     unsigned char hdr[23];\r
260 \r
261     if ( !stream.Read(hdr, WXSIZEOF(hdr)) )\r
262         return false;\r
263 \r
264     return (hdr[0] == 0x00 &&\r
265                         hdr[1] == 0x00 &&\r
266                         hdr[2] == 0x00 &&\r
267                         hdr[3] == 0x0C &&\r
268                         hdr[4] == 0x6A &&\r
269                         hdr[5] == 0x50 &&\r
270                         hdr[6] == 0x20 &&\r
271                         hdr[7] == 0x20 &&\r
272                         hdr[20] == 0x6A &&\r
273                         hdr[21] == 0x70 &&\r
274                         hdr[22] == 0x32);\r
275 }\r
276 \r
277 #endif   // wxUSE_STREAMS\r
278 \r
279 #endif   // wxUSE_LIBOPENJPEG\r