! : changed
+ : added
+February 22, 2007
++ [FOD] Added the OPJViewer Module (/OPJViewer), developed by Giuseppe Baruffa of the university of Perugia
+
February 21, 2007
+ [FOD] Algorithmic optimizations in t1.c, thanks to Guido J. !
--- /dev/null
+# Microsoft Developer Studio Project File - Name="OPJViewer" - Package Owner=<4>\r
+# Microsoft Developer Studio Generated Build File, Format Version 6.00\r
+# ** DO NOT EDIT **\r
+\r
+# TARGTYPE "Win32 (x86) Console Application" 0x0103\r
+\r
+CFG=OPJVIEWER - WIN32 RELEASE\r
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,\r
+!MESSAGE use the Export Makefile command and run\r
+!MESSAGE \r
+!MESSAGE NMAKE /f "OPJViewer.mak".\r
+!MESSAGE \r
+!MESSAGE You can specify a configuration when running NMAKE\r
+!MESSAGE by defining the macro CFG on the command line. For example:\r
+!MESSAGE \r
+!MESSAGE NMAKE /f "OPJViewer.mak" CFG="OPJVIEWER - WIN32 RELEASE"\r
+!MESSAGE \r
+!MESSAGE Possible choices for configuration are:\r
+!MESSAGE \r
+!MESSAGE "OPJViewer - Win32 Release" (based on "Win32 (x86) Console Application")\r
+!MESSAGE "OPJViewer - Win32 Debug" (based on "Win32 (x86) Console Application")\r
+!MESSAGE \r
+\r
+# Begin Project\r
+# PROP AllowPerConfigDependencies 0\r
+# PROP Scc_ProjName ""\r
+# PROP Scc_LocalPath ""\r
+CPP=cl.exe\r
+RSC=rc.exe\r
+\r
+!IF "$(CFG)" == "OPJViewer - Win32 Release"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 0\r
+# PROP BASE Output_Dir "Release"\r
+# PROP BASE Intermediate_Dir "Release"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 0\r
+# PROP Output_Dir "W32Release"\r
+# PROP Intermediate_Dir "W32Release"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c\r
+# ADD CPP /nologo /G6 /MD /GX /O2 /I "c:\programmi\wxWidgets-2.8.0\lib\vc_lib\msw" /I "c:\programmi\wxWidgets-2.8.0\include" /I ".." /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_WINDOWS" /D WINVER=0x400 /D "_MT" /D wxUSE_GUI=1 /D "wxUSE_LIBOPENJPEG" /D "OPJ_STATIC" /D "USE_JPWL" /FR /FD /c\r
+# SUBTRACT CPP /YX\r
+# ADD BASE RSC /l 0x410 /d "NDEBUG"\r
+# ADD RSC /l 0x409 /i "c:\programmi\wxWidgets-2.8.0\include" /d "NDEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386\r
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib rpcrt4.lib wsock32.lib wxzlib.lib wxregex.lib wxpng.lib wxjpeg.lib wxbase28.lib wxmsw28_core.lib wxmsw28_html.lib wxmsw28_adv.lib wxmsw28_core.lib wxbase28.lib wxtiff.lib wxjpeg.lib wxpng.lib wxzlib.lib wxregex.lib wxexpat.lib LibOpenJPEG_JPWL.lib /nologo /subsystem:windows /machine:I386 /nodefaultlib:"libcmt.lib" /libpath:"c:\programmi\wxWidgets-2.8.0\lib\vc_lib" /libpath:"..\jpwl\Release" /IGNORE:4089\r
+# SUBTRACT LINK32 /pdb:none\r
+\r
+!ELSEIF "$(CFG)" == "OPJViewer - Win32 Debug"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 1\r
+# PROP BASE Output_Dir "OPJViewer___Win32_Debug"\r
+# PROP BASE Intermediate_Dir "OPJViewer___Win32_Debug"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 1\r
+# PROP Output_Dir "W32Debug"\r
+# PROP Intermediate_Dir "W32Debug"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c\r
+# ADD CPP /nologo /MDd /Gm /GX /Zi /Od /I "C:\Programmi\wxWidgets-2.8.0\INCLUDE" /I "c:\programmi\wxWidgets-2.8.0\lib\vc_lib\msw" /I "c:\programmi\wxWidgets-2.8.0\include" /I ".." /D "_DEBUG" /D "__WXDEBUG__" /D WXDEBUG=1 /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_WINDOWS" /D WINVER=0x400 /D "_MT" /D wxUSE_GUI=1 /D "wxUSE_LIBOPENJPEG" /D "OPJ_STATIC" /D "USE_JPWL" /FR /FD /GZ /c\r
+# SUBTRACT CPP /YX\r
+# ADD BASE RSC /l 0x410 /d "_DEBUG"\r
+# ADD RSC /l 0x410 /i "c:\programmi\wxWidgets-2.8.0\include" /d "_DEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept\r
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib rpcrt4.lib wsock32.lib wxzlibd.lib wxregexd.lib wxpngd.lib wxjpegd.lib wxtiffd.lib wxbase28d.lib wxmsw28d_core.lib wxmsw28d_html.lib wxmsw28d_adv.lib LibOpenJPEG_JPWL.lib /nologo /subsystem:windows /debug /machine:I386 /nodefaultlib:"libcmtd.lib" /pdbtype:sept /libpath:"c:\programmi\wxWidgets-2.8.0\lib\vc_lib" /libpath:"..\jpwl\Debug"\r
+# SUBTRACT LINK32 /pdb:none\r
+\r
+!ENDIF \r
+\r
+# Begin Target\r
+\r
+# Name "OPJViewer - Win32 Release"\r
+# Name "OPJViewer - Win32 Debug"\r
+# Begin Group "Source Files"\r
+\r
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"\r
+# Begin Source File\r
+\r
+SOURCE=.\source\imagj2k.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\source\imagjp2.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\source\imagmj2.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\source\OPJViewer.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\source\wxj2kparser.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\source\wxjp2parser.cpp\r
+# End Source File\r
+# End Group\r
+# Begin Group "Header Files"\r
+\r
+# PROP Default_Filter "h;hpp;hxx;hm;inl"\r
+# Begin Source File\r
+\r
+SOURCE=.\source\imagj2k.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\source\imagjp2.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\source\imagmj2.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\source\OPJViewer.h\r
+# End Source File\r
+# End Group\r
+# Begin Group "Resource Files"\r
+\r
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"\r
+# Begin Source File\r
+\r
+SOURCE=.\source\icon1.xpm\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\source\icon2.xpm\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\source\icon3.xpm\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\source\icon4.xpm\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\source\icon5.xpm\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\source\OPJViewer.ico\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\source\OPJViewer.rc\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\source\OPJViewer16.xpm\r
+# End Source File\r
+# End Group\r
+# Begin Group "JPWL"\r
+\r
+# PROP Default_Filter ""\r
+# Begin Source File\r
+\r
+SOURCE=..\jpwl\crc.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\jpwl\crc.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\jpwl\jpwl.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\jpwl\jpwl.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\jpwl\jpwl_lib.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\jpwl\rs.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\jpwl\rs.h\r
+# End Source File\r
+# End Group\r
+# End Target\r
+# End Project\r
--- /dev/null
+Microsoft Developer Studio Workspace File, Format Version 6.00\r
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!\r
+\r
+###############################################################################\r
+\r
+Project: "LibOpenJPEG_JPWL"=..\jpwl\LibOpenJPEG_JPWL.dsp - Package Owner=<4>\r
+\r
+Package=<5>\r
+{{{\r
+}}}\r
+\r
+Package=<4>\r
+{{{\r
+}}}\r
+\r
+###############################################################################\r
+\r
+Project: "OPJViewer"=.\OPJViewer.dsp - Package Owner=<4>\r
+\r
+Package=<5>\r
+{{{\r
+}}}\r
+\r
+Package=<4>\r
+{{{\r
+ Begin Project Dependency\r
+ Project_Dep_Name LibOpenJPEG_JPWL\r
+ End Project Dependency\r
+}}}\r
+\r
+###############################################################################\r
+\r
+Global:\r
+\r
+Package=<5>\r
+{{{\r
+}}}\r
+\r
+Package=<3>\r
+{{{\r
+}}}\r
+\r
+###############################################################################\r
+\r
--- /dev/null
+; Script generated by the Inno Setup Script Wizard.\r
+; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!\r
+\r
+[Setup]\r
+AppName=OPJViewer\r
+AppVerName=OPJViewer 0.1 alpha\r
+AppPublisher=OpenJPEG\r
+AppPublisherURL=http://www.openjpeg.org\r
+AppSupportURL=http://www.openjpeg.org\r
+AppUpdatesURL=http://www.openjpeg.org\r
+DefaultDirName={pf}\OPJViewer\r
+DefaultGroupName=OPJViewer\r
+OutputDir=setup\r
+OutputBaseFilename=OPJViewer01alpha_setup\r
+Compression=lzma\r
+SolidCompression=yes\r
+\r
+[Languages]\r
+Name: english; MessagesFile: compiler:Default.isl\r
+\r
+[Tasks]\r
+Name: desktopicon; Description: {cm:CreateDesktopIcon}; GroupDescription: {cm:AdditionalIcons}; Flags: unchecked\r
+\r
+[Files]\r
+Source: W32Release\OPJViewer.exe; DestDir: {app}; Flags: ignoreversion\r
+; NOTE: Don't use "Flags: ignoreversion" on any shared system files\r
+\r
+[Icons]\r
+Name: {group}\OPJViewer; Filename: {app}\OPJViewer.exe\r
+Name: {group}\{cm:UninstallProgram,OPJViewer}; Filename: {uninstallexe}\r
+Name: {userdesktop}\OPJViewer; Filename: {app}\OPJViewer.exe; Tasks: desktopicon\r
+\r
+[Run]\r
+Filename: {app}\OPJViewer.exe; Description: {cm:LaunchProgram,OPJViewer}; Flags: nowait postinstall skipifsilent\r
--- /dev/null
+/*\r
+ * Copyright (c) 2007, Digital Signal Processing Laboratory, Università degli studi di Perugia (UPG), Italy\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * 1. Redistributions of source code must retain the above copyright\r
+ * notice, this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ * notice, this list of conditions and the following disclaimer in the\r
+ * documentation and/or other materials provided with the distribution.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'\r
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\r
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
+ * POSSIBILITY OF SUCH DAMAGE.\r
+ */\r
+/////////////////////////////////////////////////////////////////////////////\r
+// Name: sashtest.cpp\r
+// Purpose: Layout/sash sample\r
+// Author: Julian Smart\r
+// Modified by:\r
+// Created: 04/01/98\r
+// RCS-ID: $Id: sashtest.cpp,v 1.18 2005/08/23 15:54:35 ABX Exp $\r
+// Copyright: (c) Julian Smart\r
+// Licence: wxWindows license\r
+/////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r
+// Name: treetest.cpp\r
+// Purpose: wxTreeCtrl sample\r
+// Author: Julian Smart\r
+// Modified by:\r
+// Created: 04/01/98\r
+// RCS-ID: $Id: treetest.cpp,v 1.110 2006/11/04 11:26:51 VZ Exp $\r
+// Copyright: (c) Julian Smart\r
+// Licence: wxWindows license\r
+/////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r
+// Name: dialogs.cpp\r
+// Purpose: Common dialogs demo\r
+// Author: Julian Smart\r
+// Modified by: ABX (2004) - adjustements for conditional building + new menu\r
+// Created: 04/01/98\r
+// RCS-ID: $Id: dialogs.cpp,v 1.163 2006/11/04 10:57:24 VZ Exp $\r
+// Copyright: (c) Julian Smart\r
+// Licence: wxWindows license\r
+/////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r
+// Name: thread.cpp\r
+// Purpose: wxWidgets thread sample\r
+// Author: Guilhem Lavaux, Vadim Zeitlin\r
+// Modified by:\r
+// Created: 06/16/98\r
+// RCS-ID: $Id: thread.cpp,v 1.26 2006/10/02 05:36:28 PC Exp $\r
+// Copyright: (c) 1998-2002 wxWidgets team\r
+// Licence: wxWindows license\r
+/////////////////////////////////////////////////////////////////////////////\r
+///////////////////////////////////////////////////////////////////////////////\r
+// Name: samples/image/image.cpp\r
+// Purpose: sample showing operations with wxImage\r
+// Author: Robert Roebling\r
+// Modified by:\r
+// Created: 1998\r
+// RCS-ID: $Id: image.cpp,v 1.120 2006/12/06 17:13:11 VZ Exp $\r
+// Copyright: (c) 1998-2005 Robert Roebling\r
+// License: wxWindows licence\r
+///////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r
+// Name: samples/console/console.cpp\r
+// Purpose: A sample console (as opposed to GUI) program using wxWidgets\r
+// Author: Vadim Zeitlin\r
+// Modified by:\r
+// Created: 04.10.99\r
+// RCS-ID: $Id: console.cpp,v 1.206 2006/11/12 19:55:19 VZ Exp $\r
+// Copyright: (c) 1999 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>\r
+// Licence: wxWindows license\r
+/////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r
+// Name: samples/notebook/notebook.cpp\r
+// Purpose: a sample demonstrating notebook usage\r
+// Author: Julian Smart\r
+// Modified by: Dimitri Schoolwerth\r
+// Created: 26/10/98\r
+// RCS-ID: $Id: notebook.cpp,v 1.49 2006/11/04 18:24:07 RR Exp $\r
+// Copyright: (c) 1998-2002 wxWidgets team\r
+// License: wxWindows license\r
+/////////////////////////////////////////////////////////////////////////////\r
+#include "OPJViewer.h"\r
+\r
+OPJFrame *frame = NULL;\r
+wxList my_children;\r
+\r
+IMPLEMENT_APP(OPJViewerApp)\r
+\r
+// For drawing lines in a canvas\r
+long xpos = -1;\r
+long ypos = -1;\r
+\r
+int winNumber = 1;\r
+\r
+// Initialise this in OnInit, not statically\r
+bool OPJViewerApp::OnInit(void)\r
+{\r
+#if wxUSE_UNICODE\r
+ wxChar **wxArgv = new wxChar *[argc + 1];\r
+\r
+ {\r
+ int n;\r
+\r
+ for (n = 0; n < argc; n++ )\r
+ {\r
+ wxMB2WXbuf warg = wxConvertMB2WX(argv[n]);\r
+ wxArgv[n] = wxStrdup(warg);\r
+ }\r
+\r
+ wxArgv[n] = NULL;\r
+ }\r
+#else // !wxUSE_UNICODE\r
+ #define wxArgv argv\r
+#endif // wxUSE_UNICODE/!wxUSE_UNICODE\r
+\r
+#if wxUSE_CMDLINE_PARSER\r
+ static const wxCmdLineEntryDesc cmdLineDesc[] =\r
+ {\r
+ { wxCMD_LINE_SWITCH, _T("h"), _T("help"), _T("show this help message"),\r
+ wxCMD_LINE_VAL_NONE, wxCMD_LINE_OPTION_HELP },\r
+ /*{ wxCMD_LINE_SWITCH, _T("v"), _T("verbose"), _T("be verbose") },\r
+ { wxCMD_LINE_SWITCH, _T("q"), _T("quiet"), _T("be quiet") },\r
+\r
+ { wxCMD_LINE_OPTION, _T("o"), _T("output"), _T("output file") },\r
+ { wxCMD_LINE_OPTION, _T("i"), _T("input"), _T("input dir") },\r
+ { wxCMD_LINE_OPTION, _T("s"), _T("size"), _T("output block size"),\r
+ wxCMD_LINE_VAL_NUMBER },\r
+ { wxCMD_LINE_OPTION, _T("d"), _T("date"), _T("output file date"),\r
+ wxCMD_LINE_VAL_DATE },*/\r
+\r
+ { wxCMD_LINE_PARAM, NULL, NULL, _T("input file"),\r
+ wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL | wxCMD_LINE_PARAM_MULTIPLE },\r
+\r
+ { wxCMD_LINE_NONE }\r
+ };\r
+\r
+ wxCmdLineParser parser(cmdLineDesc, argc, wxArgv);\r
+\r
+ /*parser.AddOption(_T("project_name"), _T(""), _T("full path to project file"),\r
+ wxCMD_LINE_VAL_STRING,\r
+ wxCMD_LINE_OPTION_MANDATORY | wxCMD_LINE_NEEDS_SEPARATOR);*/\r
+\r
+ switch ( parser.Parse() )\r
+ {\r
+ case -1:\r
+ wxLogMessage(_T("Help was given, terminating."));\r
+ break;\r
+\r
+ case 0:\r
+ ShowCmdLine(parser);\r
+ break;\r
+\r
+ default:\r
+ wxLogMessage(_T("Syntax error detected."));\r
+ break;\r
+ }\r
+#endif // wxUSE_CMDLINE_PARSER\r
+\r
+ //wxInitAllImageHandlers();\r
+#if wxUSE_LIBJPEG\r
+ wxImage::AddHandler( new wxJPEGHandler );\r
+#endif\r
+#if wxUSE_LIBOPENJPEG\r
+ wxImage::AddHandler( new wxJ2KHandler );\r
+ wxImage::AddHandler( new wxJP2Handler );\r
+ wxImage::AddHandler( new wxMJ2Handler );\r
+#endif\r
+\r
+\r
+ // Create the main frame window\r
+\r
+ frame = new OPJFrame(NULL, wxID_ANY, OPJ_APPLICATION_TITLEBAR, wxDefaultPosition, wxSize(800, 600),\r
+ wxDEFAULT_FRAME_STYLE |\r
+ wxNO_FULL_REPAINT_ON_RESIZE |\r
+ wxHSCROLL | wxVSCROLL);\r
+\r
+ // Give it an icon (this is ignored in MDI mode: uses resources)\r
+#ifdef __WXMSW__\r
+ frame->SetIcon(wxIcon(_T("OPJViewer16")));\r
+#endif\r
+\r
+ frame->Show(true);\r
+\r
+ SetTopWindow(frame);\r
+\r
+ return true;\r
+}\r
+\r
+void OPJViewerApp::ShowCmdLine(const wxCmdLineParser& parser)\r
+{\r
+ wxString s = _T("Command line parsed successfully:\nInput files: ");\r
+\r
+ size_t count = parser.GetParamCount();\r
+ for ( size_t param = 0; param < count; param++ )\r
+ {\r
+ s << parser.GetParam(param) << ';';\r
+\r
+ m_filelist.Add(parser.GetParam(param));\r
+ }\r
+\r
+ /*s << '\n'\r
+ << _T("Verbose:\t") << (parser.Found(_T("v")) ? _T("yes") : _T("no")) << '\n'\r
+ << _T("Quiet:\t") << (parser.Found(_T("q")) ? _T("yes") : _T("no")) << '\n';\r
+\r
+ wxString strVal;\r
+ long lVal;\r
+ wxDateTime dt;\r
+ if ( parser.Found(_T("o"), &strVal) )\r
+ s << _T("Output file:\t") << strVal << '\n';\r
+ if ( parser.Found(_T("i"), &strVal) )\r
+ s << _T("Input dir:\t") << strVal << '\n';\r
+ if ( parser.Found(_T("s"), &lVal) )\r
+ s << _T("Size:\t") << lVal << '\n';\r
+ if ( parser.Found(_T("d"), &dt) )\r
+ s << _T("Date:\t") << dt.FormatISODate() << '\n';\r
+ if ( parser.Found(_T("project_name"), &strVal) )\r
+ s << _T("Project:\t") << strVal << '\n';*/\r
+\r
+ //wxLogMessage(s);\r
+}\r
+\r
+// OPJFrame events\r
+BEGIN_EVENT_TABLE(OPJFrame, wxMDIParentFrame)\r
+ EVT_MENU(SASHTEST_ABOUT, OPJFrame::OnAbout)\r
+ EVT_MENU(SASHTEST_NEW_WINDOW, OPJFrame::OnFileOpen)\r
+ EVT_SIZE(OPJFrame::OnSize)\r
+ EVT_MENU(SASHTEST_QUIT, OPJFrame::OnQuit)\r
+ EVT_MENU(SASHTEST_TOGGLE_WINDOW, OPJFrame::OnToggleWindow)\r
+ EVT_SASH_DRAGGED_RANGE(ID_WINDOW_TOP, ID_WINDOW_BOTTOM, OPJFrame::OnSashDrag)\r
+ EVT_NOTEBOOK_PAGE_CHANGED(LEFT_NOTEBOOK_ID, OPJFrame::OnNotebook)\r
+END_EVENT_TABLE()\r
+\r
+// this is the frame constructor\r
+OPJFrame::OPJFrame(wxWindow *parent, const wxWindowID id, const wxString& title,\r
+ const wxPoint& pos, const wxSize& size, const long style)\r
+ : wxMDIParentFrame(parent, id, title, pos, size, style)\r
+{\r
+ // file menu and its items\r
+ wxMenu *file_menu = new wxMenu;\r
+\r
+ file_menu->Append(SASHTEST_NEW_WINDOW, wxT("&Open\tCtrl+O"));\r
+ file_menu->SetHelpString(SASHTEST_NEW_WINDOW, wxT("Open one or more files"));\r
+\r
+ file_menu->Append(SASHTEST_TOGGLE_WINDOW, wxT("&Toggle browser\tCtrl+T"));\r
+ file_menu->SetHelpString(SASHTEST_TOGGLE_WINDOW, wxT("Toggle the left browsing pane"));\r
+\r
+ file_menu->Append(SASHTEST_QUIT, wxT("&Exit\tCtrl+Q"));\r
+ file_menu->SetHelpString(SASHTEST_QUIT, wxT("Quit this program"));\r
+\r
+ // help menu and its items\r
+ wxMenu *help_menu = new wxMenu;\r
+\r
+ help_menu->Append(SASHTEST_ABOUT, wxT("&About\tF1"));\r
+ help_menu->SetHelpString(SASHTEST_ABOUT, wxT("Basic info on the program"));\r
+\r
+ // the whole menubar\r
+ wxMenuBar *menu_bar = new wxMenuBar;\r
+ menu_bar->Append(file_menu, wxT("&File"));\r
+ menu_bar->Append(help_menu, wxT("&Help"));\r
+\r
+ // Associate the menu bar with the frame\r
+ SetMenuBar(menu_bar);\r
+\r
+ // the status bar\r
+ CreateStatusBar();\r
+\r
+ // the logging window\r
+ loggingWindow = new wxSashLayoutWindow(this, ID_WINDOW_BOTTOM,\r
+ wxDefaultPosition, wxSize(400, 130),\r
+ wxNO_BORDER | wxSW_3D | wxCLIP_CHILDREN\r
+ );\r
+ loggingWindow->SetDefaultSize(wxSize(1000, 130));\r
+ loggingWindow->SetOrientation(wxLAYOUT_HORIZONTAL);\r
+ loggingWindow->SetAlignment(wxLAYOUT_BOTTOM);\r
+ //loggingWindow->SetBackgroundColour(wxColour(0, 0, 255));\r
+ loggingWindow->SetSashVisible(wxSASH_TOP, true);\r
+\r
+ // create the bottom notebook\r
+ m_bookCtrlbottom = new wxNotebook(loggingWindow, BOTTOM_NOTEBOOK_ID,\r
+ wxDefaultPosition, wxDefaultSize,\r
+ wxBK_LEFT);\r
+\r
+ // create the text control of the logger\r
+ m_textCtrl = new wxTextCtrl(m_bookCtrlbottom, wxID_ANY, wxT(""),\r
+ wxDefaultPosition, wxDefaultSize,\r
+ wxTE_MULTILINE | wxSUNKEN_BORDER | wxTE_READONLY \r
+ );\r
+ m_textCtrl->SetValue(_T("Logging window\n"));\r
+\r
+ // add it to the notebook\r
+ m_bookCtrlbottom->AddPage(m_textCtrl, wxT("Log"));\r
+\r
+ // create the text control of the browser\r
+ m_textCtrlbrowse = new wxTextCtrl(m_bookCtrlbottom, wxID_ANY, wxT(""),\r
+ wxDefaultPosition, wxDefaultSize,\r
+ wxTE_MULTILINE | wxSUNKEN_BORDER | wxTE_READONLY \r
+ );\r
+ m_textCtrlbrowse->SetValue(_T("Browsing window\n"));\r
+\r
+ // add it the notebook\r
+ m_bookCtrlbottom->AddPage(m_textCtrlbrowse, wxT("Peek"));\r
+\r
+ // the browser window\r
+ markerTreeWindow = new wxSashLayoutWindow(this, ID_WINDOW_LEFT1,\r
+ wxDefaultPosition, wxSize(300, 30),\r
+ wxNO_BORDER | wxSW_3D | wxCLIP_CHILDREN\r
+ );\r
+ markerTreeWindow->SetDefaultSize(wxSize(300, 1000));\r
+ markerTreeWindow->SetOrientation(wxLAYOUT_VERTICAL);\r
+ markerTreeWindow->SetAlignment(wxLAYOUT_LEFT);\r
+ //markerTreeWindow->SetBackgroundColour(wxColour(0, 255, 0));\r
+ markerTreeWindow->SetSashVisible(wxSASH_RIGHT, true);\r
+ markerTreeWindow->SetExtraBorderSize(0);\r
+\r
+ // create the browser notebook\r
+ m_bookCtrl = new wxNotebook(markerTreeWindow, LEFT_NOTEBOOK_ID,\r
+ wxDefaultPosition, wxDefaultSize,\r
+ wxBK_TOP);\r
+\r
+\r
+#if wxUSE_LOG\r
+#ifdef __WXMOTIF__\r
+ // For some reason, we get a memcpy crash in wxLogStream::DoLogStream\r
+ // on gcc/wxMotif, if we use wxLogTextCtl. Maybe it's just gcc?\r
+ delete wxLog::SetActiveTarget(new wxLogStderr);\r
+#else\r
+ // set our text control as the log target\r
+ wxLogTextCtrl *logWindow = new wxLogTextCtrl(m_textCtrl);\r
+ delete wxLog::SetActiveTarget(logWindow);\r
+#endif\r
+#endif // wxUSE_LOG\r
+\r
+ // if there are files on the command line, open them\r
+ /*if (!wxGetApp().m_filelist.IsEmpty()) {\r
+ wxLogMessage(wxT("Habemus files!!!"));\r
+ wxArrayString paths, filenames;\r
+ for (int f = 0; f < wxGetApp().m_filelist.GetCount(); f++) {\r
+ paths.Add(wxFileName(wxGetApp().m_filelist[f]).GetFullPath());\r
+ filenames.Add(wxFileName(wxGetApp().m_filelist[f]).GetFullName());\r
+ }\r
+ OpenFiles(paths, filenames);\r
+ }*/\r
+}\r
+\r
+// this is the frame destructor\r
+OPJFrame::~OPJFrame(void)\r
+{\r
+ // delete all possible things\r
+ delete m_bookCtrl;\r
+ m_bookCtrl = NULL;\r
+\r
+ delete markerTreeWindow;\r
+ markerTreeWindow = NULL;\r
+\r
+ delete m_textCtrl;\r
+ m_textCtrl = NULL;\r
+\r
+ delete m_bookCtrlbottom;\r
+ m_bookCtrlbottom = NULL;\r
+\r
+ delete loggingWindow;\r
+ loggingWindow = NULL;\r
+}\r
+\r
+void OPJFrame::OnNotebook(wxNotebookEvent& event)\r
+{\r
+ int sel = event.GetSelection();\r
+ long childnum;\r
+\r
+ m_bookCtrl->GetPageText(sel).ToLong(&childnum);\r
+\r
+ m_childhash[childnum]->Activate();\r
+\r
+ wxLogMessage(wxString::Format(wxT("Selection changed (now %d --> %d)"), childnum, m_childhash[childnum]->m_winnumber));\r
+\r
+}\r
+\r
+\r
+void OPJFrame::Resize(int number)\r
+{\r
+ wxSize size = GetClientSize();\r
+}\r
+\r
+void OPJFrame::OnQuit(wxCommandEvent& WXUNUSED(event))\r
+{\r
+ Close(true);\r
+}\r
+\r
+// about window for the frame\r
+void OPJFrame::OnAbout(wxCommandEvent& WXUNUSED(event))\r
+{\r
+ wxMessageBox(wxString::Format(OPJ_APPLICATION_TITLEBAR\r
+ wxT("\n\n")\r
+ wxT("Built with %s and OpenJPEG ")\r
+ wxT(OPENJPEG_VERSION)\r
+ wxT("\non ") wxT(__DATE__) wxT(", ") wxT(__TIME__)\r
+ wxT("\nRunning under %s\n\n")\r
+ OPJ_APPLICATION_COPYRIGHT,\r
+ wxVERSION_STRING,\r
+ wxGetOsDescription().c_str()\r
+ ),\r
+ wxT("About ") OPJ_APPLICATION_NAME,\r
+ wxOK | wxICON_INFORMATION,\r
+ this\r
+ );\r
+}\r
+\r
+void OPJFrame::OnToggleWindow(wxCommandEvent& WXUNUSED(event))\r
+{\r
+ if (markerTreeWindow->IsShown())\r
+ {\r
+ markerTreeWindow->Show(false);\r
+ }\r
+ else\r
+ {\r
+ markerTreeWindow->Show(true);\r
+ }\r
+#if wxUSE_MDI_ARCHITECTURE\r
+ wxLayoutAlgorithm layout;\r
+ layout.LayoutMDIFrame(this);\r
+#endif // wxUSE_MDI_ARCHITECTURE\r
+}\r
+\r
+void OPJFrame::OnSashDrag(wxSashEvent& event)\r
+{\r
+ if (event.GetDragStatus() == wxSASH_STATUS_OUT_OF_RANGE)\r
+ return;\r
+\r
+ switch (event.GetId())\r
+ {\r
+ case ID_WINDOW_LEFT1:\r
+ {\r
+ markerTreeWindow->SetDefaultSize(wxSize(event.GetDragRect().width, 1000));\r
+ break;\r
+ }\r
+ case ID_WINDOW_BOTTOM:\r
+ {\r
+ loggingWindow->SetDefaultSize(wxSize(1000, event.GetDragRect().height));\r
+ break;\r
+ }\r
+ }\r
+\r
+#if wxUSE_MDI_ARCHITECTURE\r
+ wxLayoutAlgorithm layout;\r
+ layout.LayoutMDIFrame(this);\r
+#endif // wxUSE_MDI_ARCHITECTURE\r
+\r
+ // Leaves bits of itself behind sometimes\r
+ GetClientWindow()->Refresh();\r
+}\r
+\r
+// physically open the files\r
+void OPJFrame::OpenFiles(wxArrayString paths, wxArrayString filenames)\r
+{\r
+\r
+ size_t count = paths.GetCount();\r
+ for ( size_t n = 0; n < count; n++ )\r
+ {\r
+ wxString msg, s;\r
+ s.Printf(_T("File %d: %s (%s)\n"),\r
+ (int)n, paths[n].c_str(), filenames[n].c_str());\r
+\r
+ msg += s;\r
+ //s.Printf(_T("Filter index: %d"), dialog.GetFilterIndex());\r
+ msg += s;\r
+\r
+ /*wxMessageDialog dialog2(this, msg, _T("Selected files"));\r
+ dialog2.ShowModal();*/\r
+\r
+ // Make another frame, containing a canvas\r
+ OPJChildFrame *subframe = new OPJChildFrame(frame,\r
+ paths[n],\r
+ winNumber,\r
+ _T("Canvas Frame"),\r
+ wxDefaultPosition, wxSize(300, 300),\r
+ wxDEFAULT_FRAME_STYLE |\r
+ wxNO_FULL_REPAINT_ON_RESIZE);\r
+ m_childhash[winNumber] = subframe;\r
+\r
+ // create own marker tree\r
+ long tstyle = wxTR_DEFAULT_STYLE | wxSUNKEN_BORDER | \r
+ #ifndef NO_VARIABLE_HEIGHT\r
+ wxTR_HAS_VARIABLE_ROW_HEIGHT /*|*/\r
+ #endif\r
+ /*wxTR_EDIT_LABELS*/;\r
+\r
+ m_treehash[winNumber] = new OPJMarkerTree(m_bookCtrl, paths[n], wxT("Parsing..."), TreeTest_Ctrl,\r
+ wxDefaultPosition, wxDefaultSize,\r
+ tstyle);\r
+\r
+ m_bookCtrl->AddPage(m_treehash[winNumber],\r
+ wxString::Format(wxT("%u"), winNumber), false);\r
+\r
+ for (int p = 0; p < m_bookCtrl->GetPageCount(); p++) {\r
+\r
+ if (m_bookCtrl->GetPageText(p) == wxString::Format(wxT("%u"), winNumber)) {\r
+ m_bookCtrl->ChangeSelection(p);\r
+ break;\r
+ }\r
+\r
+ }\r
+\r
+ winNumber++;\r
+ \r
+ }\r
+\r
+\r
+}\r
+\r
+void OPJFrame::OnFileOpen(wxCommandEvent& WXUNUSED(event))\r
+{\r
+ wxString wildcards =\r
+#ifdef __WXMOTIF__\r
+ wxT("JPEG 2000 files (*.jp2,*.j2k,*.j2c,*.mj2)|*.*j*2*");\r
+#else\r
+ wxT("JPEG 2000 files (*.jp2,*.j2k,*.j2c,*.mj2)|*.jp2;*.j2k;*.j2c;*.mj2|JPEG files (*.jpg)|*.jpg|All files|*");\r
+#endif\r
+ wxFileDialog dialog(this, _T("Open JPEG 2000 file(s)"),\r
+ wxEmptyString, wxEmptyString, wildcards,\r
+ wxFD_OPEN|wxFD_MULTIPLE);\r
+\r
+ if (dialog.ShowModal() == wxID_OK)\r
+ {\r
+ wxArrayString paths, filenames;\r
+\r
+ dialog.GetPaths(paths);\r
+ dialog.GetFilenames(filenames);\r
+\r
+ OpenFiles(paths, filenames);\r
+\r
+ }\r
+\r
+}\r
+\r
+BEGIN_EVENT_TABLE(OPJCanvas, wxScrolledWindow)\r
+ EVT_MOUSE_EVENTS(OPJCanvas::OnEvent)\r
+END_EVENT_TABLE()\r
+\r
+// Define a constructor for my canvas\r
+OPJCanvas::OPJCanvas(wxFileName fname, wxWindow *parent, const wxPoint& pos, const wxSize& size)\r
+ : wxScrolledWindow(parent, wxID_ANY, pos, size,\r
+ wxSUNKEN_BORDER | wxNO_FULL_REPAINT_ON_RESIZE)\r
+{\r
+ SetBackgroundColour(OPJ_CANVAS_COLOUR);\r
+\r
+ m_fname = fname;\r
+\r
+ OPJDecoThread *dthread = CreateDecoThread();\r
+\r
+ if (dthread->Run() != wxTHREAD_NO_ERROR)\r
+ wxLogMessage(wxT("Can't start deco thread!"));\r
+ else\r
+ wxLogMessage(_T("New deco thread started."));\r
+\r
+}\r
+\r
+OPJDecoThread *OPJCanvas::CreateDecoThread(void)\r
+{\r
+ OPJDecoThread *dthread = new OPJDecoThread(this);\r
+\r
+ if (dthread->Create() != wxTHREAD_NO_ERROR)\r
+ wxLogError(wxT("Can't create deco thread!"));\r
+\r
+ wxCriticalSectionLocker enter(wxGetApp().m_deco_critsect);\r
+ wxGetApp().m_deco_threads.Add(dthread);\r
+\r
+ return dthread;\r
+}\r
+\r
+// Define the repainting behaviour\r
+void OPJCanvas::OnDraw(wxDC& dc)\r
+{\r
+ /*dc.SetFont(*wxSWISS_FONT);\r
+ dc.SetPen(*wxBLACK_PEN);\r
+ dc.DrawText(_T("Image drawing canvas"), 10, 10);\r
+ dc.DrawLine(8, 22, 300, 22);*/\r
+ if (m_image.Ok()) {\r
+ dc.DrawBitmap(m_image, OPJ_CANVAS_BORDER, OPJ_CANVAS_BORDER);\r
+ } else {\r
+ dc.SetFont(*wxSWISS_FONT);\r
+ dc.SetPen(*wxBLACK_PEN);\r
+ dc.DrawText(_T("Decoding image, please wait..."), 40, 50);\r
+ }\r
+\r
+ /*dc.SetFont(*wxSWISS_FONT);\r
+ dc.SetPen(*wxGREEN_PEN);\r
+ dc.DrawLine(0, 0, 200, 200);\r
+ dc.DrawLine(200, 0, 0, 200);\r
+\r
+ dc.SetBrush(*wxCYAN_BRUSH);\r
+ dc.SetPen(*wxRED_PEN);\r
+ dc.DrawRectangle(100, 100, 100, 50);\r
+ dc.DrawRoundedRectangle(150, 150, 100, 50, 20);\r
+\r
+ dc.DrawEllipse(250, 250, 100, 50);\r
+#if wxUSE_SPLINES\r
+ dc.DrawSpline(50, 200, 50, 100, 200, 10);\r
+#endif // wxUSE_SPLINES\r
+ dc.DrawLine(50, 230, 200, 230);\r
+ dc.DrawText(_T("This is a test string"), 50, 230);\r
+\r
+ wxPoint points[3];\r
+ points[0].x = 200; points[0].y = 300;\r
+ points[1].x = 100; points[1].y = 400;\r
+ points[2].x = 300; points[2].y = 400;\r
+\r
+ dc.DrawPolygon(3, points);*/\r
+}\r
+\r
+// This implements a tiny doodling program! Drag the mouse using\r
+// the left button.\r
+void OPJCanvas::OnEvent(wxMouseEvent& event)\r
+{\r
+ wxClientDC dc(this);\r
+ PrepareDC(dc);\r
+\r
+ wxPoint pt(event.GetLogicalPosition(dc));\r
+\r
+ if (xpos > -1 && ypos > -1 && event.Dragging())\r
+ {\r
+ dc.SetPen(*wxBLACK_PEN);\r
+ dc.DrawLine(xpos, ypos, pt.x, pt.y);\r
+ }\r
+ xpos = pt.x;\r
+ ypos = pt.y;\r
+}\r
+\r
+void OPJFrame::OnSize(wxSizeEvent& WXUNUSED(event))\r
+{\r
+#if wxUSE_MDI_ARCHITECTURE\r
+ wxLayoutAlgorithm layout;\r
+ layout.LayoutMDIFrame(this);\r
+#endif // wxUSE_MDI_ARCHITECTURE\r
+}\r
+\r
+// Note that SASHTEST_NEW_WINDOW and SASHTEST_ABOUT commands get passed\r
+// to the parent window for processing, so no need to\r
+// duplicate event handlers here.\r
+\r
+BEGIN_EVENT_TABLE(OPJChildFrame, wxMDIChildFrame)\r
+ /*EVT_MENU(SASHTEST_CHILD_QUIT, OPJChildFrame::OnQuit)*/\r
+ EVT_CLOSE(OPJChildFrame::OnClose)\r
+ EVT_SET_FOCUS(OPJChildFrame::OnGotFocus)\r
+ /*EVT_KILL_FOCUS(OPJChildFrame::OnLostFocus)*/\r
+END_EVENT_TABLE()\r
+\r
+OPJChildFrame::OPJChildFrame(OPJFrame *parent, wxFileName fname, int winnumber, const wxString& title, const wxPoint& pos, const wxSize& size,\r
+const long style):\r
+ wxMDIChildFrame(parent, wxID_ANY, title, pos, size, style)\r
+{\r
+ m_frame = (OPJFrame *) parent;\r
+ m_canvas = NULL;\r
+ my_children.Append(this);\r
+ m_fname = fname;\r
+ m_winnumber = winnumber;\r
+ SetTitle(wxString::Format(_T("%d: "), m_winnumber) + m_fname.GetFullName());\r
+\r
+\r
+ // Give it an icon (this is ignored in MDI mode: uses resources)\r
+#ifdef __WXMSW__\r
+ SetIcon(wxIcon(_T("sashtest_icn")));\r
+#endif\r
+\r
+#if wxUSE_STATUSBAR\r
+ // Give it a status line\r
+ //CreateStatusBar();\r
+#endif // wxUSE_STATUSBAR\r
+\r
+ // Make a menubar\r
+ /*wxMenu *file_menu = new wxMenu;\r
+\r
+ file_menu->Append(SASHTEST_NEW_WINDOW, _T("&Open\tCtrl+O"));\r
+ file_menu->Append(SASHTEST_CHILD_QUIT, _T("&Close\tCtrl+C"));\r
+ file_menu->Append(SASHTEST_QUIT, _T("&Exit\tCtrl+Q"));\r
+\r
+ wxMenu *option_menu = new wxMenu;\r
+\r
+ // Dummy option\r
+ option_menu->Append(SASHTEST_REFRESH, _T("&Refresh picture"));\r
+\r
+ wxMenu *help_menu = new wxMenu;\r
+ help_menu->Append(SASHTEST_ABOUT, _T("&About\tF1"));\r
+\r
+ wxMenuBar *menu_bar = new wxMenuBar;\r
+\r
+ menu_bar->Append(file_menu, _T("&File"));\r
+ menu_bar->Append(option_menu, _T("&Options"));\r
+ menu_bar->Append(help_menu, _T("&Help"));\r
+\r
+ // Associate the menu bar with the frame\r
+ SetMenuBar(menu_bar);*/\r
+\r
+\r
+ int width, height;\r
+ GetClientSize(&width, &height);\r
+\r
+ OPJCanvas *canvas = new OPJCanvas(fname, this, wxPoint(0, 0), wxSize(width, height));\r
+ canvas->SetCursor(wxCursor(wxCURSOR_PENCIL));\r
+ m_canvas = canvas;\r
+\r
+ // Give it scrollbars\r
+ canvas->SetScrollbars(20, 20, 5, 5);\r
+\r
+ Show(true);\r
+ Maximize(true);\r
+\r
+\r
+ /*wxSize gsize = m_frame->m_bookCtrl->GetClientSize();\r
+ m_frame->m_treehash[m_winnumber]->SetSize(0, 0, gsize.x, gsize.y);*/\r
+\r
+ /*m_frame->Resize(m_winnumber);*/\r
+ /*m_frame->m_treehash[0]->Show(false);\r
+ m_frame->m_treehash[m_winnumber]->Show(true);*/\r
+ /*m_frame->Resize(m_winnumber);*/\r
+\r
+ /*wxLogError(wxString::Format(wxT("Created tree %d (0x%x)"), m_winnumber, m_frame->m_treehash[m_winnumber]));*/\r
+\r
+}\r
+\r
+OPJChildFrame::~OPJChildFrame(void)\r
+{\r
+ my_children.DeleteObject(this);\r
+}\r
+\r
+/*void OPJChildFrame::OnQuit(wxCommandEvent& WXUNUSED(event))\r
+{\r
+ for (int p = 0; p < m_frame->m_bookCtrl->GetPageCount(); p++) {\r
+\r
+ if (m_frame->m_bookCtrl->GetPageText(p) == wxString::Format(wxT("%u"), m_winnumber)) {\r
+ m_frame->m_bookCtrl->DeletePage(p);;\r
+ break;\r
+ }\r
+\r
+ }\r
+\r
+ Close(true);\r
+}*/\r
+\r
+void OPJChildFrame::OnClose(wxCloseEvent& event)\r
+{\r
+ for (int p = 0; p < m_frame->m_bookCtrl->GetPageCount(); p++) {\r
+\r
+ if (m_frame->m_bookCtrl->GetPageText(p) == wxString::Format(wxT("%u"), m_winnumber)) {\r
+ m_frame->m_bookCtrl->DeletePage(p);\r
+ break;\r
+ }\r
+\r
+ }\r
+ Destroy();\r
+\r
+ wxLogMessage(wxString::Format(wxT("Closed: %d"), m_winnumber));\r
+\r
+}\r
+\r
+void OPJChildFrame::OnActivate(wxActivateEvent& event)\r
+{\r
+ /*if (event.GetActive() && m_canvas)\r
+ m_canvas->SetFocus();*/\r
+}\r
+\r
+void OPJChildFrame::OnGotFocus(wxFocusEvent& event)\r
+{\r
+ // we need to check if the notebook is being destroyed or not\r
+ if (!m_frame->m_bookCtrl)\r
+ return;\r
+\r
+ for (int p = 0; p < m_frame->m_bookCtrl->GetPageCount(); p++) {\r
+\r
+ if (m_frame->m_bookCtrl->GetPageText(p) == wxString::Format(wxT("%u"), m_winnumber)) {\r
+ m_frame->m_bookCtrl->ChangeSelection(p);\r
+ break;\r
+ }\r
+\r
+ }\r
+\r
+ wxLogMessage(wxString::Format(wxT("Got focus: %d (%x)"), m_winnumber, event.GetWindow()));\r
+}\r
+\r
+/*void OPJChildFrame::OnLostFocus(wxFocusEvent& event)\r
+{\r
+ wxLogMessage(wxString::Format(wxT("Lost focus: %d (%x)"), m_winnumber, event.GetWindow()));\r
+\r
+}*/\r
+\r
+#if USE_GENERIC_TREECTRL\r
+BEGIN_EVENT_TABLE(OPJMarkerTree, wxGenericTreeCtrl)\r
+#else\r
+BEGIN_EVENT_TABLE(OPJMarkerTree, wxTreeCtrl)\r
+#endif\r
+ /*EVT_TREE_BEGIN_DRAG(TreeTest_Ctrl, OPJMarkerTree::OnBeginDrag)\r
+ EVT_TREE_BEGIN_RDRAG(TreeTest_Ctrl, OPJMarkerTree::OnBeginRDrag)\r
+ EVT_TREE_END_DRAG(TreeTest_Ctrl, OPJMarkerTree::OnEndDrag)*/\r
+ /*EVT_TREE_BEGIN_LABEL_EDIT(TreeTest_Ctrl, OPJMarkerTree::OnBeginLabelEdit)\r
+ EVT_TREE_END_LABEL_EDIT(TreeTest_Ctrl, OPJMarkerTree::OnEndLabelEdit)*/\r
+ /*EVT_TREE_DELETE_ITEM(TreeTest_Ctrl, OPJMarkerTree::OnDeleteItem)*/\r
+#if 0 // there are so many of those that logging them causes flicker\r
+ /*EVT_TREE_GET_INFO(TreeTest_Ctrl, OPJMarkerTree::OnGetInfo)*/\r
+#endif\r
+ /*EVT_TREE_SET_INFO(TreeTest_Ctrl, OPJMarkerTree::OnSetInfo)\r
+ EVT_TREE_ITEM_EXPANDED(TreeTest_Ctrl, OPJMarkerTree::OnItemExpanded)*/\r
+ EVT_TREE_ITEM_EXPANDING(TreeTest_Ctrl, OPJMarkerTree::OnItemExpanding)\r
+ /*EVT_TREE_ITEM_COLLAPSED(TreeTest_Ctrl, OPJMarkerTree::OnItemCollapsed)\r
+ EVT_TREE_ITEM_COLLAPSING(TreeTest_Ctrl, OPJMarkerTree::OnItemCollapsing)*/\r
+\r
+ EVT_TREE_SEL_CHANGED(TreeTest_Ctrl, OPJMarkerTree::OnSelChanged)\r
+ /*EVT_TREE_SEL_CHANGING(TreeTest_Ctrl, OPJMarkerTree::OnSelChanging)*/\r
+ /*EVT_TREE_KEY_DOWN(TreeTest_Ctrl, OPJMarkerTree::OnTreeKeyDown)*/\r
+ /*EVT_TREE_ITEM_ACTIVATED(TreeTest_Ctrl, OPJMarkerTree::OnItemActivated)*/\r
+\r
+ // so many differents ways to handle right mouse button clicks...\r
+ /*EVT_CONTEXT_MENU(OPJMarkerTree::OnContextMenu)*/\r
+ // EVT_TREE_ITEM_MENU is the preferred event for creating context menus\r
+ // on a tree control, because it includes the point of the click or item,\r
+ // meaning that no additional placement calculations are required.\r
+ /*EVT_TREE_ITEM_MENU(TreeTest_Ctrl, OPJMarkerTree::OnItemMenu)*/\r
+ /*EVT_TREE_ITEM_RIGHT_CLICK(TreeTest_Ctrl, OPJMarkerTree::OnItemRClick)*/\r
+\r
+ /*EVT_RIGHT_DOWN(OPJMarkerTree::OnRMouseDown)\r
+ EVT_RIGHT_UP(OPJMarkerTree::OnRMouseUp)\r
+ EVT_RIGHT_DCLICK(OPJMarkerTree::OnRMouseDClick)*/\r
+END_EVENT_TABLE()\r
+\r
+// OPJMarkerTree implementation\r
+#if USE_GENERIC_TREECTRL\r
+IMPLEMENT_DYNAMIC_CLASS(OPJMarkerTree, wxGenericTreeCtrl)\r
+#else\r
+IMPLEMENT_DYNAMIC_CLASS(OPJMarkerTree, wxTreeCtrl)\r
+#endif\r
+\r
+OPJMarkerTree::OPJMarkerTree(wxWindow *parent, wxFileName fname, wxString name, const wxWindowID id,\r
+ const wxPoint& pos, const wxSize& size,\r
+ long style)\r
+ : wxTreeCtrl(parent, id, pos, size, style)\r
+{\r
+ m_reverseSort = false;\r
+ m_fname = fname;\r
+\r
+ m_peektextCtrl = ((OPJFrame *) (parent->GetParent()->GetParent()))->m_textCtrlbrowse;\r
+ CreateImageList();\r
+\r
+ // Add some items to the tree\r
+ //AddTestItemsToTree(5, 5);\r
+ int image = wxGetApp().ShowImages() ? OPJMarkerTree::TreeCtrlIcon_Folder : -1;\r
+ wxTreeItemId rootId = AddRoot(name,\r
+ image, image,\r
+ new OPJMarkerData(name));\r
+\r
+ OPJParseThread *pthread = CreateParseThread();\r
+ if (pthread->Run() != wxTHREAD_NO_ERROR)\r
+ wxLogMessage(wxT("Can't start parse thread!"));\r
+ else\r
+ wxLogMessage(_T("New parse thread started."));\r
+}\r
+\r
+void OPJMarkerTree::CreateImageList(int size)\r
+{\r
+ if ( size == -1 )\r
+ {\r
+ SetImageList(NULL);\r
+ return;\r
+ }\r
+ if ( size == 0 )\r
+ size = m_imageSize;\r
+ else\r
+ m_imageSize = size;\r
+\r
+ // Make an image list containing small icons\r
+ wxImageList *images = new wxImageList(size, size, true);\r
+\r
+ // should correspond to TreeCtrlIcon_xxx enum\r
+ wxBusyCursor wait;\r
+ wxIcon icons[5];\r
+ icons[0] = wxIcon(icon1_xpm);\r
+ icons[1] = wxIcon(icon2_xpm);\r
+ icons[2] = wxIcon(icon3_xpm);\r
+ icons[3] = wxIcon(icon4_xpm);\r
+ icons[4] = wxIcon(icon5_xpm);\r
+\r
+ int sizeOrig = icons[0].GetWidth();\r
+ for ( size_t i = 0; i < WXSIZEOF(icons); i++ )\r
+ {\r
+ if ( size == sizeOrig )\r
+ {\r
+ images->Add(icons[i]);\r
+ }\r
+ else\r
+ {\r
+ images->Add(wxBitmap(wxBitmap(icons[i]).ConvertToImage().Rescale(size, size)));\r
+ }\r
+ }\r
+\r
+ AssignImageList(images);\r
+}\r
+\r
+#if USE_GENERIC_TREECTRL || !defined(__WXMSW__)\r
+void OPJMarkerTree::CreateButtonsImageList(int size)\r
+{\r
+ if ( size == -1 )\r
+ {\r
+ SetButtonsImageList(NULL);\r
+ return;\r
+ }\r
+\r
+ // Make an image list containing small icons\r
+ wxImageList *images = new wxImageList(size, size, true);\r
+\r
+ // should correspond to TreeCtrlIcon_xxx enum\r
+ wxBusyCursor wait;\r
+ wxIcon icons[4];\r
+ icons[0] = wxIcon(icon3_xpm); // closed\r
+ icons[1] = wxIcon(icon3_xpm); // closed, selected\r
+ icons[2] = wxIcon(icon5_xpm); // open\r
+ icons[3] = wxIcon(icon5_xpm); // open, selected\r
+\r
+ for ( size_t i = 0; i < WXSIZEOF(icons); i++ )\r
+ {\r
+ int sizeOrig = icons[i].GetWidth();\r
+ if ( size == sizeOrig )\r
+ {\r
+ images->Add(icons[i]);\r
+ }\r
+ else\r
+ {\r
+ images->Add(wxBitmap(wxBitmap(icons[i]).ConvertToImage().Rescale(size, size)));\r
+ }\r
+ }\r
+\r
+ AssignButtonsImageList(images);\r
+#else\r
+void OPJMarkerTree::CreateButtonsImageList(int WXUNUSED(size))\r
+{\r
+#endif\r
+}\r
+\r
+void OPJParseThread::LoadFile(wxFileName fname)\r
+{\r
+ wxTreeItemId rootid;\r
+\r
+ // this is the root node\r
+ int image = wxGetApp().ShowImages() ? m_tree->TreeCtrlIcon_Folder : -1;\r
+\r
+ if (this->m_parentid) {\r
+ // leaf of a tree\r
+ rootid = m_parentid;\r
+ m_tree->SetItemText(rootid, wxT("Parsing..."));\r
+\r
+ } else {\r
+\r
+ // delete the existing tree hierarchy\r
+ m_tree->DeleteAllItems();\r
+\r
+ // new tree\r
+ rootid = m_tree->AddRoot(wxT("Parsing..."),\r
+ image,\r
+ image,\r
+ new OPJMarkerData(fname.GetFullPath())\r
+ );\r
+ //m_tree->SetItemFont(rootid, *wxITALIC_FONT);\r
+ m_tree->SetItemBold(rootid);\r
+ }\r
+\r
+ // open the file\r
+ wxFile m_file(fname.GetFullPath().c_str(), wxFile::read);\r
+\r
+ // what is the extension?\r
+ if ((fname.GetExt() == wxT("j2k")) || (fname.GetExt() == wxT("j2c"))) {\r
+\r
+ // parse the file\r
+ ParseJ2KFile(&m_file, 0, m_file.Length(), rootid);\r
+\r
+ } else if ((fname.GetExt() == wxT("jp2")) || (fname.GetExt() == wxT("mj2"))) {\r
+\r
+ // parse the file\r
+ if (this->m_parentid) {\r
+ //WriteText(wxT("Only a subsection of jp2"));\r
+ OPJMarkerData *data = (OPJMarkerData *) m_tree->GetItemData(rootid);\r
+ ParseJ2KFile(&m_file, data->m_start, data->m_length, rootid);\r
+ m_tree->Expand(rootid);\r
+\r
+ } else\r
+ // as usual\r
+ ParseJP2File(&m_file, 0, m_file.Length(), rootid);\r
+\r
+ } else {\r
+\r
+ // unknown extension\r
+ WriteText(wxT("Unknown file format!"));\r
+\r
+ }\r
+\r
+ // close the file\r
+ m_file.Close();\r
+\r
+ // this is the root node\r
+ if (this->m_parentid)\r
+ m_tree->SetItemText(rootid, wxT("Codestream"));\r
+ else\r
+ m_tree->SetItemText(rootid, fname.GetFullName());\r
+ \r
+ WriteText(wxT("Parsing finished!"));\r
+}\r
+\r
+/*int OPJMarkerTree::OnCompareItems(const wxTreeItemId& item1,\r
+ const wxTreeItemId& item2)\r
+{\r
+ if ( m_reverseSort )\r
+ {\r
+ // just exchange 1st and 2nd items\r
+ return wxTreeCtrl::OnCompareItems(item2, item1);\r
+ }\r
+ else\r
+ {\r
+ return wxTreeCtrl::OnCompareItems(item1, item2);\r
+ }\r
+}*/\r
+\r
+/*void OPJMarkerTree::AddItemsRecursively(const wxTreeItemId& idParent,\r
+ size_t numChildren,\r
+ size_t depth,\r
+ size_t folder)\r
+{\r
+ if ( depth > 0 )\r
+ {\r
+ bool hasChildren = depth > 1;\r
+\r
+ wxString str;\r
+ for ( size_t n = 0; n < numChildren; n++ )\r
+ {\r
+ // at depth 1 elements won't have any more children\r
+ if ( hasChildren )\r
+ str.Printf(wxT("%s child %u"), wxT("Folder"), unsigned(n + 1));\r
+ else\r
+ str.Printf(wxT("%s child %u.%u"), wxT("File"), unsigned(folder), unsigned(n + 1));\r
+\r
+ // here we pass to AppendItem() normal and selected item images (we\r
+ // suppose that selected image follows the normal one in the enum)\r
+ int image, imageSel;\r
+ if ( wxGetApp().ShowImages() )\r
+ {\r
+ image = depth == 1 ? TreeCtrlIcon_File : TreeCtrlIcon_Folder;\r
+ imageSel = image + 1;\r
+ }\r
+ else\r
+ {\r
+ image = imageSel = -1;\r
+ }\r
+ wxTreeItemId id = AppendItem(idParent, str, image, imageSel,\r
+ new OPJMarkerData(str));\r
+\r
+ // and now we also set the expanded one (only for the folders)\r
+ if ( hasChildren && wxGetApp().ShowImages() )\r
+ {\r
+ SetItemImage(id, TreeCtrlIcon_FolderOpened,\r
+ wxTreeItemIcon_Expanded);\r
+ }\r
+\r
+ // remember the last child for OnEnsureVisible()\r
+ if ( !hasChildren && n == numChildren - 1 )\r
+ {\r
+ m_lastItem = id;\r
+ }\r
+\r
+ AddItemsRecursively(id, numChildren, depth - 1, n + 1);\r
+ }\r
+ }\r
+ //else: done!\r
+}*/\r
+\r
+/*void OPJMarkerTree::AddTestItemsToTree(size_t numChildren,\r
+ size_t depth)\r
+{\r
+ int image = wxGetApp().ShowImages() ? OPJMarkerTree::TreeCtrlIcon_Folder : -1;\r
+ wxTreeItemId rootId = AddRoot(wxT("Root"),\r
+ image, image,\r
+ new OPJMarkerData(wxT("Root item")));\r
+ if ( image != -1 )\r
+ {\r
+ SetItemImage(rootId, TreeCtrlIcon_FolderOpened, wxTreeItemIcon_Expanded);\r
+ }\r
+\r
+ AddItemsRecursively(rootId, numChildren, depth, 0);\r
+\r
+ // set some colours/fonts for testing\r
+ SetItemFont(rootId, *wxITALIC_FONT);\r
+\r
+ wxTreeItemIdValue cookie;\r
+ wxTreeItemId id = GetFirstChild(rootId, cookie);\r
+ SetItemTextColour(id, *wxBLUE);\r
+\r
+ id = GetNextChild(rootId, cookie);\r
+ id = GetNextChild(rootId, cookie);\r
+ SetItemTextColour(id, *wxRED);\r
+ SetItemBackgroundColour(id, *wxLIGHT_GREY);\r
+}*/\r
+\r
+/*void OPJMarkerTree::GetItemsRecursively(const wxTreeItemId& idParent,\r
+ wxTreeItemIdValue cookie)\r
+{\r
+ wxTreeItemId id;\r
+\r
+ if ( !cookie )\r
+ id = GetFirstChild(idParent, cookie);\r
+ else\r
+ id = GetNextChild(idParent, cookie);\r
+\r
+ if ( !id.IsOk() )\r
+ return;\r
+\r
+ wxString text = GetItemText(id);\r
+ wxLogMessage(text);\r
+\r
+ if (ItemHasChildren(id))\r
+ GetItemsRecursively(id);\r
+\r
+ GetItemsRecursively(idParent, cookie);\r
+}*/\r
+\r
+/*void OPJMarkerTree::DoToggleIcon(const wxTreeItemId& item)\r
+{\r
+ int image = (GetItemImage(item) == TreeCtrlIcon_Folder)\r
+ ? TreeCtrlIcon_File\r
+ : TreeCtrlIcon_Folder;\r
+ SetItemImage(item, image, wxTreeItemIcon_Normal);\r
+\r
+ image = (GetItemImage(item) == TreeCtrlIcon_FolderSelected)\r
+ ? TreeCtrlIcon_FileSelected\r
+ : TreeCtrlIcon_FolderSelected;\r
+ SetItemImage(item, image, wxTreeItemIcon_Selected);\r
+}*/\r
+\r
+void OPJMarkerTree::LogEvent(const wxChar *name, const wxTreeEvent& event)\r
+{\r
+ wxTreeItemId item = event.GetItem();\r
+ wxString text;\r
+ if ( item.IsOk() )\r
+ text << _T('"') << GetItemText(item).c_str() << _T('"');\r
+ else\r
+ text = _T("invalid item");\r
+ wxLogMessage(wxT("%s(%s)"), name, text.c_str());\r
+}\r
+\r
+OPJParseThread *OPJMarkerTree::CreateParseThread(wxTreeItemId parentid)\r
+{\r
+ OPJParseThread *pthread = new OPJParseThread(this, parentid);\r
+\r
+ if (pthread->Create() != wxTHREAD_NO_ERROR)\r
+ wxLogError(wxT("Can't create parse thread!"));\r
+\r
+ wxCriticalSectionLocker enter(wxGetApp().m_parse_critsect);\r
+ wxGetApp().m_parse_threads.Add(pthread);\r
+\r
+ return pthread;\r
+}\r
+\r
+\r
+/*// avoid repetition\r
+#define TREE_EVENT_HANDLER(name) \\r
+void OPJMarkerTree::name(wxTreeEvent& event) \\r
+{ \\r
+ LogEvent(_T(#name), event); \\r
+ SetLastItem(wxTreeItemId()); \\r
+ event.Skip(); \\r
+}*/\r
+\r
+/*TREE_EVENT_HANDLER(OnBeginRDrag)*/\r
+/*TREE_EVENT_HANDLER(OnDeleteItem)*/\r
+/*TREE_EVENT_HANDLER(OnGetInfo)\r
+TREE_EVENT_HANDLER(OnSetInfo)*/\r
+/*TREE_EVENT_HANDLER(OnItemExpanded)\r
+TREE_EVENT_HANDLER(OnItemExpanding)*/\r
+/*TREE_EVENT_HANDLER(OnItemCollapsed)*/\r
+/*TREE_EVENT_HANDLER(OnSelChanged)\r
+TREE_EVENT_HANDLER(OnSelChanging)*/\r
+\r
+/*#undef TREE_EVENT_HANDLER*/\r
+\r
+void OPJMarkerTree::OnItemExpanding(wxTreeEvent& event)\r
+{\r
+ wxTreeItemId item = event.GetItem();\r
+ OPJMarkerData* data = (OPJMarkerData *) GetItemData(item);\r
+ wxString text;\r
+\r
+ if (item.IsOk())\r
+ text << wxT('"') << GetItemText(item).c_str() << wxT('"');\r
+ else\r
+ text = wxT("invalid item");\r
+\r
+ if (strcmp(data->GetDesc1(), wxT("INFO-CSTREAM")))\r
+ return;\r
+\r
+ wxLogMessage(wxT("Expanding... (%s -> %s, %s, %d, %d)"),\r
+ text.c_str(), data->GetDesc1(), data->GetDesc2(),\r
+ data->m_start, data->m_length);\r
+\r
+ // the codestream box is being asked for expansion\r
+ wxTreeItemIdValue cookie;\r
+ if (!GetFirstChild(item, cookie).IsOk()) {\r
+ OPJParseThread *pthread = CreateParseThread(item);\r
+ if (pthread->Run() != wxTHREAD_NO_ERROR)\r
+ wxLogMessage(wxT("Can't start parse thread!"));\r
+ else\r
+ wxLogMessage(wxT("New parse thread started."));\r
+ }\r
+}\r
+\r
+void OPJMarkerTree::OnSelChanged(wxTreeEvent& event)\r
+{\r
+#define BUNCH_LINESIZE 24\r
+#define BUNCH_NUMLINES 6\r
+\r
+ wxTreeItemId item = event.GetItem();\r
+ OPJMarkerData* data = (OPJMarkerData *) GetItemData(item);\r
+ wxString text;\r
+ int l, c, pos = 0, pre_pos;\r
+ unsigned char buffer[BUNCH_LINESIZE * BUNCH_NUMLINES];\r
+\r
+ m_peektextCtrl->Clear();\r
+\r
+ /*wxTextAttr myattr = m_peektextCtrl->GetDefaultStyle();\r
+ myattr.SetFont(wxFont(10, wxFONTFAMILY_TELETYPE, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL));\r
+ m_peektextCtrl->SetDefaultStyle(myattr);*/\r
+\r
+ text << wxString::Format(wxT("Selected... (%s -> %s, %s, %d, %d)"),\r
+ text.c_str(), data->GetDesc1(), data->GetDesc2(),\r
+ data->m_start, data->m_length) << wxT("\n");\r
+\r
+ // open the file and browse a little\r
+ wxFile *fp = new wxFile(m_fname.GetFullPath().c_str(), wxFile::read);\r
+\r
+ // go to position claimed\r
+ fp->Seek(data->m_start, wxFromStart);\r
+\r
+ // read a bunch\r
+ int max_read = wxMin(WXSIZEOF(buffer), data->m_length - data->m_start + 1);\r
+ fp->Read(buffer, max_read);\r
+\r
+ pos = 0;\r
+ for (l = 0; l < BUNCH_NUMLINES; l++) {\r
+\r
+ text << wxString::Format(wxT("%08d:"), data->m_start + pos);\r
+\r
+ pre_pos = pos;\r
+\r
+ // add hex browsing text\r
+ for (c = 0; c < BUNCH_LINESIZE; c++) {\r
+\r
+ if (!(c % 8))\r
+ text << wxT(" ");\r
+\r
+ if (pos < max_read) {\r
+ text << wxString::Format(wxT("%02X "), wxT(buffer[pos]));\r
+ } else\r
+ text << wxT(" ");\r
+ pos++;\r
+ }\r
+\r
+ text << wxT(" ");\r
+\r
+ // add char browsing text\r
+ for (c = 0; c < BUNCH_LINESIZE; c++) {\r
+\r
+ if (pre_pos < max_read) {\r
+ if ((buffer[pre_pos] == '\n') || (buffer[pre_pos] == '\t'))\r
+ buffer[pre_pos] = ' ';\r
+ text << wxString::Format(wxT("%c."), wxChar(buffer[pre_pos]));\r
+ } else\r
+ text << wxT(" ");\r
+ pre_pos++;\r
+ }\r
+\r
+ text << wxT("\n");\r
+\r
+ }\r
+\r
+ // close the file\r
+ fp->Close();\r
+\r
+ m_peektextCtrl->WriteText(text);\r
+}\r
+\r
+/*void LogKeyEvent(const wxChar *name, const wxKeyEvent& event)\r
+{\r
+ wxString key;\r
+ long keycode = event.GetKeyCode();\r
+ {\r
+ switch ( keycode )\r
+ {\r
+ case WXK_BACK: key = wxT("BACK"); break;\r
+ case WXK_TAB: key = wxT("TAB"); break;\r
+ case WXK_RETURN: key = wxT("RETURN"); break;\r
+ case WXK_ESCAPE: key = wxT("ESCAPE"); break;\r
+ case WXK_SPACE: key = wxT("SPACE"); break;\r
+ case WXK_DELETE: key = wxT("DELETE"); break;\r
+ case WXK_START: key = wxT("START"); break;\r
+ case WXK_LBUTTON: key = wxT("LBUTTON"); break;\r
+ case WXK_RBUTTON: key = wxT("RBUTTON"); break;\r
+ case WXK_CANCEL: key = wxT("CANCEL"); break;\r
+ case WXK_MBUTTON: key = wxT("MBUTTON"); break;\r
+ case WXK_CLEAR: key = wxT("CLEAR"); break;\r
+ case WXK_SHIFT: key = wxT("SHIFT"); break;\r
+ case WXK_ALT: key = wxT("ALT"); break;\r
+ case WXK_CONTROL: key = wxT("CONTROL"); break;\r
+ case WXK_MENU: key = wxT("MENU"); break;\r
+ case WXK_PAUSE: key = wxT("PAUSE"); break;\r
+ case WXK_CAPITAL: key = wxT("CAPITAL"); break;\r
+ case WXK_END: key = wxT("END"); break;\r
+ case WXK_HOME: key = wxT("HOME"); break;\r
+ case WXK_LEFT: key = wxT("LEFT"); break;\r
+ case WXK_UP: key = wxT("UP"); break;\r
+ case WXK_RIGHT: key = wxT("RIGHT"); break;\r
+ case WXK_DOWN: key = wxT("DOWN"); break;\r
+ case WXK_SELECT: key = wxT("SELECT"); break;\r
+ case WXK_PRINT: key = wxT("PRINT"); break;\r
+ case WXK_EXECUTE: key = wxT("EXECUTE"); break;\r
+ case WXK_SNAPSHOT: key = wxT("SNAPSHOT"); break;\r
+ case WXK_INSERT: key = wxT("INSERT"); break;\r
+ case WXK_HELP: key = wxT("HELP"); break;\r
+ case WXK_NUMPAD0: key = wxT("NUMPAD0"); break;\r
+ case WXK_NUMPAD1: key = wxT("NUMPAD1"); break;\r
+ case WXK_NUMPAD2: key = wxT("NUMPAD2"); break;\r
+ case WXK_NUMPAD3: key = wxT("NUMPAD3"); break;\r
+ case WXK_NUMPAD4: key = wxT("NUMPAD4"); break;\r
+ case WXK_NUMPAD5: key = wxT("NUMPAD5"); break;\r
+ case WXK_NUMPAD6: key = wxT("NUMPAD6"); break;\r
+ case WXK_NUMPAD7: key = wxT("NUMPAD7"); break;\r
+ case WXK_NUMPAD8: key = wxT("NUMPAD8"); break;\r
+ case WXK_NUMPAD9: key = wxT("NUMPAD9"); break;\r
+ case WXK_MULTIPLY: key = wxT("MULTIPLY"); break;\r
+ case WXK_ADD: key = wxT("ADD"); break;\r
+ case WXK_SEPARATOR: key = wxT("SEPARATOR"); break;\r
+ case WXK_SUBTRACT: key = wxT("SUBTRACT"); break;\r
+ case WXK_DECIMAL: key = wxT("DECIMAL"); break;\r
+ case WXK_DIVIDE: key = wxT("DIVIDE"); break;\r
+ case WXK_F1: key = wxT("F1"); break;\r
+ case WXK_F2: key = wxT("F2"); break;\r
+ case WXK_F3: key = wxT("F3"); break;\r
+ case WXK_F4: key = wxT("F4"); break;\r
+ case WXK_F5: key = wxT("F5"); break;\r
+ case WXK_F6: key = wxT("F6"); break;\r
+ case WXK_F7: key = wxT("F7"); break;\r
+ case WXK_F8: key = wxT("F8"); break;\r
+ case WXK_F9: key = wxT("F9"); break;\r
+ case WXK_F10: key = wxT("F10"); break;\r
+ case WXK_F11: key = wxT("F11"); break;\r
+ case WXK_F12: key = wxT("F12"); break;\r
+ case WXK_F13: key = wxT("F13"); break;\r
+ case WXK_F14: key = wxT("F14"); break;\r
+ case WXK_F15: key = wxT("F15"); break;\r
+ case WXK_F16: key = wxT("F16"); break;\r
+ case WXK_F17: key = wxT("F17"); break;\r
+ case WXK_F18: key = wxT("F18"); break;\r
+ case WXK_F19: key = wxT("F19"); break;\r
+ case WXK_F20: key = wxT("F20"); break;\r
+ case WXK_F21: key = wxT("F21"); break;\r
+ case WXK_F22: key = wxT("F22"); break;\r
+ case WXK_F23: key = wxT("F23"); break;\r
+ case WXK_F24: key = wxT("F24"); break;\r
+ case WXK_NUMLOCK: key = wxT("NUMLOCK"); break;\r
+ case WXK_SCROLL: key = wxT("SCROLL"); break;\r
+ case WXK_PAGEUP: key = wxT("PAGEUP"); break;\r
+ case WXK_PAGEDOWN: key = wxT("PAGEDOWN"); break;\r
+ case WXK_NUMPAD_SPACE: key = wxT("NUMPAD_SPACE"); break;\r
+ case WXK_NUMPAD_TAB: key = wxT("NUMPAD_TAB"); break;\r
+ case WXK_NUMPAD_ENTER: key = wxT("NUMPAD_ENTER"); break;\r
+ case WXK_NUMPAD_F1: key = wxT("NUMPAD_F1"); break;\r
+ case WXK_NUMPAD_F2: key = wxT("NUMPAD_F2"); break;\r
+ case WXK_NUMPAD_F3: key = wxT("NUMPAD_F3"); break;\r
+ case WXK_NUMPAD_F4: key = wxT("NUMPAD_F4"); break;\r
+ case WXK_NUMPAD_HOME: key = wxT("NUMPAD_HOME"); break;\r
+ case WXK_NUMPAD_LEFT: key = wxT("NUMPAD_LEFT"); break;\r
+ case WXK_NUMPAD_UP: key = wxT("NUMPAD_UP"); break;\r
+ case WXK_NUMPAD_RIGHT: key = wxT("NUMPAD_RIGHT"); break;\r
+ case WXK_NUMPAD_DOWN: key = wxT("NUMPAD_DOWN"); break;\r
+ case WXK_NUMPAD_PAGEUP: key = wxT("NUMPAD_PAGEUP"); break;\r
+ case WXK_NUMPAD_PAGEDOWN: key = wxT("NUMPAD_PAGEDOWN"); break;\r
+ case WXK_NUMPAD_END: key = wxT("NUMPAD_END"); break;\r
+ case WXK_NUMPAD_BEGIN: key = wxT("NUMPAD_BEGIN"); break;\r
+ case WXK_NUMPAD_INSERT: key = wxT("NUMPAD_INSERT"); break;\r
+ case WXK_NUMPAD_DELETE: key = wxT("NUMPAD_DELETE"); break;\r
+ case WXK_NUMPAD_EQUAL: key = wxT("NUMPAD_EQUAL"); break;\r
+ case WXK_NUMPAD_MULTIPLY: key = wxT("NUMPAD_MULTIPLY"); break;\r
+ case WXK_NUMPAD_ADD: key = wxT("NUMPAD_ADD"); break;\r
+ case WXK_NUMPAD_SEPARATOR: key = wxT("NUMPAD_SEPARATOR"); break;\r
+ case WXK_NUMPAD_SUBTRACT: key = wxT("NUMPAD_SUBTRACT"); break;\r
+ case WXK_NUMPAD_DECIMAL: key = wxT("NUMPAD_DECIMAL"); break;\r
+\r
+ default:\r
+ {\r
+ if ( keycode < 128 && wxIsprint((int)keycode) )\r
+ key.Printf(wxT("'%c'"), (char)keycode);\r
+ else if ( keycode > 0 && keycode < 27 )\r
+ key.Printf(_("Ctrl-%c"), wxT('A') + keycode - 1);\r
+ else\r
+ key.Printf(wxT("unknown (%ld)"), keycode);\r
+ }\r
+ }\r
+ }\r
+\r
+ wxLogMessage( wxT("%s event: %s (flags = %c%c%c%c)"),\r
+ name,\r
+ key.c_str(),\r
+ event.ControlDown() ? wxT('C') : wxT('-'),\r
+ event.AltDown() ? wxT('A') : wxT('-'),\r
+ event.ShiftDown() ? wxT('S') : wxT('-'),\r
+ event.MetaDown() ? wxT('M') : wxT('-'));\r
+}\r
+\r
+void OPJMarkerTree::OnTreeKeyDown(wxTreeEvent& event)\r
+{\r
+ LogKeyEvent(wxT("Tree key down "), event.GetKeyEvent());\r
+\r
+ event.Skip();\r
+}*/\r
+\r
+/*void OPJMarkerTree::OnBeginDrag(wxTreeEvent& event)\r
+{\r
+ // need to explicitly allow drag\r
+ if ( event.GetItem() != GetRootItem() )\r
+ {\r
+ m_draggedItem = event.GetItem();\r
+\r
+ wxLogMessage(wxT("OnBeginDrag: started dragging %s"),\r
+ GetItemText(m_draggedItem).c_str());\r
+\r
+ event.Allow();\r
+ }\r
+ else\r
+ {\r
+ wxLogMessage(wxT("OnBeginDrag: this item can't be dragged."));\r
+ }\r
+}\r
+\r
+void OPJMarkerTree::OnEndDrag(wxTreeEvent& event)\r
+{\r
+ wxTreeItemId itemSrc = m_draggedItem,\r
+ itemDst = event.GetItem();\r
+ m_draggedItem = (wxTreeItemId)0l;\r
+\r
+ // where to copy the item?\r
+ if ( itemDst.IsOk() && !ItemHasChildren(itemDst) )\r
+ {\r
+ // copy to the parent then\r
+ itemDst = GetItemParent(itemDst);\r
+ }\r
+\r
+ if ( !itemDst.IsOk() )\r
+ {\r
+ wxLogMessage(wxT("OnEndDrag: can't drop here."));\r
+\r
+ return;\r
+ }\r
+\r
+ wxString text = GetItemText(itemSrc);\r
+ wxLogMessage(wxT("OnEndDrag: '%s' copied to '%s'."),\r
+ text.c_str(), GetItemText(itemDst).c_str());\r
+\r
+ // just do append here - we could also insert it just before/after the item\r
+ // on which it was dropped, but this requires slightly more work... we also\r
+ // completely ignore the client data and icon of the old item but could\r
+ // copy them as well.\r
+ //\r
+ // Finally, we only copy one item here but we might copy the entire tree if\r
+ // we were dragging a folder.\r
+ int image = wxGetApp().ShowImages() ? TreeCtrlIcon_File : -1;\r
+ AppendItem(itemDst, text, image);\r
+}*/\r
+\r
+/*void OPJMarkerTree::OnBeginLabelEdit(wxTreeEvent& event)\r
+{\r
+ wxLogMessage(wxT("OnBeginLabelEdit"));\r
+\r
+ // for testing, prevent this item's label editing\r
+ wxTreeItemId itemId = event.GetItem();\r
+ if ( IsTestItem(itemId) )\r
+ {\r
+ wxMessageBox(wxT("You can't edit this item."));\r
+\r
+ event.Veto();\r
+ }\r
+ else if ( itemId == GetRootItem() )\r
+ {\r
+ // test that it is possible to change the text of the item being edited\r
+ SetItemText(itemId, _T("Editing root item"));\r
+ }\r
+}\r
+\r
+void OPJMarkerTree::OnEndLabelEdit(wxTreeEvent& event)\r
+{\r
+ wxLogMessage(wxT("OnEndLabelEdit"));\r
+\r
+ // don't allow anything except letters in the labels\r
+ if ( !event.GetLabel().IsWord() )\r
+ {\r
+ wxMessageBox(wxT("The new label should be a single word."));\r
+\r
+ event.Veto();\r
+ }\r
+}*/\r
+\r
+/*void OPJMarkerTree::OnItemCollapsing(wxTreeEvent& event)\r
+{\r
+ wxLogMessage(wxT("OnItemCollapsing"));\r
+\r
+ // for testing, prevent the user from collapsing the first child folder\r
+ wxTreeItemId itemId = event.GetItem();\r
+ if ( IsTestItem(itemId) )\r
+ {\r
+ wxMessageBox(wxT("You can't collapse this item."));\r
+\r
+ event.Veto();\r
+ }\r
+}*/\r
+\r
+/*void OPJMarkerTree::OnItemActivated(wxTreeEvent& event)\r
+{\r
+ // show some info about this item\r
+ wxTreeItemId itemId = event.GetItem();\r
+ OPJMarkerData *item = (OPJMarkerData *)GetItemData(itemId);\r
+\r
+ if ( item != NULL )\r
+ {\r
+ item->ShowInfo(this);\r
+ }\r
+\r
+ wxLogMessage(wxT("OnItemActivated"));\r
+}*/\r
+\r
+/*void OPJMarkerTree::OnItemMenu(wxTreeEvent& event)\r
+{\r
+ wxTreeItemId itemId = event.GetItem();\r
+ OPJMarkerData *item = itemId.IsOk() ? (OPJMarkerData *)GetItemData(itemId)\r
+ : NULL;\r
+\r
+ wxLogMessage(wxT("OnItemMenu for item \"%s\""), item ? item->GetDesc()\r
+ : _T(""));\r
+\r
+ event.Skip();\r
+}*/\r
+\r
+/*void OPJMarkerTree::OnContextMenu(wxContextMenuEvent& event)\r
+{\r
+ wxPoint pt = event.GetPosition();\r
+ wxTreeItemId item;\r
+ wxLogMessage(wxT("OnContextMenu at screen coords (%i, %i)"), pt.x, pt.y);\r
+\r
+ // check if event was generated by keyboard (MSW-specific?)\r
+ if ( pt.x == -1 && pt.y == -1 ) //(this is how MSW indicates it)\r
+ {\r
+ if ( !HasFlag(wxTR_MULTIPLE) )\r
+ item = GetSelection();\r
+\r
+ // attempt to guess where to show the menu\r
+ if ( item.IsOk() )\r
+ {\r
+ // if an item was clicked, show menu to the right of it\r
+ wxRect rect;\r
+ GetBoundingRect(item, rect, true );// only the label\r
+ pt = wxPoint(rect.GetRight(), rect.GetTop());\r
+ }\r
+ else\r
+ {\r
+ pt = wxPoint(0, 0);\r
+ }\r
+ }\r
+ else // event was generated by mouse, use supplied coords\r
+ {\r
+ pt = ScreenToClient(pt);\r
+ item = HitTest(pt);\r
+ }\r
+\r
+ ShowMenu(item, pt);\r
+}*/\r
+\r
+/*void OPJMarkerTree::ShowMenu(wxTreeItemId id, const wxPoint& pt)\r
+{\r
+ wxString title;\r
+ if ( id.IsOk() )\r
+ {\r
+ title << wxT("Menu for ") << GetItemText(id);\r
+ }\r
+ else\r
+ {\r
+ title = wxT("Menu for no particular item");\r
+ }\r
+\r
+#if wxUSE_MENUS\r
+ wxMenu menu(title);\r
+ menu.Append(TreeTest_About, wxT("&About..."));\r
+ menu.AppendSeparator();\r
+ menu.Append(TreeTest_Highlight, wxT("&Highlight item"));\r
+ menu.Append(TreeTest_Dump, wxT("&Dump"));\r
+\r
+ PopupMenu(&menu, pt);\r
+#endif // wxUSE_MENUS\r
+}*/\r
+\r
+/*void OPJMarkerTree::OnItemRClick(wxTreeEvent& event)\r
+{\r
+ wxTreeItemId itemId = event.GetItem();\r
+ OPJMarkerData *item = itemId.IsOk() ? (OPJMarkerData *)GetItemData(itemId)\r
+ : NULL;\r
+\r
+ wxLogMessage(wxT("Item \"%s\" right clicked"), item ? item->GetDesc()\r
+ : _T(""));\r
+\r
+ event.Skip();\r
+}*/\r
+\r
+/*\r
+void OPJMarkerTree::OnRMouseDown(wxMouseEvent& event)\r
+{\r
+ wxLogMessage(wxT("Right mouse button down"));\r
+\r
+ event.Skip();\r
+}\r
+\r
+void OPJMarkerTree::OnRMouseUp(wxMouseEvent& event)\r
+{\r
+ wxLogMessage(wxT("Right mouse button up"));\r
+\r
+ event.Skip();\r
+}\r
+\r
+void OPJMarkerTree::OnRMouseDClick(wxMouseEvent& event)\r
+{\r
+ wxTreeItemId id = HitTest(event.GetPosition());\r
+ if ( !id )\r
+ wxLogMessage(wxT("No item under mouse"));\r
+ else\r
+ {\r
+ OPJMarkerData *item = (OPJMarkerData *)GetItemData(id);\r
+ if ( item )\r
+ wxLogMessage(wxT("Item '%s' under mouse"), item->GetDesc());\r
+ }\r
+\r
+ event.Skip();\r
+}\r
+*/\r
+\r
+static inline const wxChar *Bool2String(bool b)\r
+{\r
+ return b ? wxT("") : wxT("not ");\r
+}\r
+\r
+void OPJMarkerData::ShowInfo(wxTreeCtrl *tree)\r
+{\r
+ wxLogMessage(wxT("Item '%s': %sselected, %sexpanded, %sbold,\n")\r
+ wxT("%u children (%u immediately under this item)."),\r
+ m_desc.c_str(),\r
+ Bool2String(tree->IsSelected(GetId())),\r
+ Bool2String(tree->IsExpanded(GetId())),\r
+ Bool2String(tree->IsBold(GetId())),\r
+ unsigned(tree->GetChildrenCount(GetId())),\r
+ unsigned(tree->GetChildrenCount(GetId(), false)));\r
+}\r
+\r
+/////////////////////////////////////////////////////////////////////\r
+// Decoding thread class\r
+/////////////////////////////////////////////////////////////////////\r
+\r
+OPJDecoThread::OPJDecoThread(OPJCanvas *canvas)\r
+ : wxThread()\r
+{\r
+ m_count = 0;\r
+ m_canvas = canvas;\r
+}\r
+\r
+void OPJDecoThread::WriteText(const wxString& text)\r
+{\r
+ wxString msg;\r
+\r
+ // before doing any GUI calls we must ensure that this thread is the only\r
+ // one doing it!\r
+\r
+ wxMutexGuiEnter();\r
+\r
+ msg << text;\r
+ m_canvas->WriteText(msg);\r
+\r
+ wxMutexGuiLeave();\r
+}\r
+\r
+void OPJDecoThread::OnExit()\r
+{\r
+ wxCriticalSectionLocker locker(wxGetApp().m_deco_critsect);\r
+\r
+ wxArrayThread& dthreads = wxGetApp().m_deco_threads;\r
+ dthreads.Remove(this);\r
+\r
+ if (dthreads.IsEmpty() )\r
+ {\r
+ // signal the main thread that there are no more threads left if it is\r
+ // waiting for us\r
+ if (wxGetApp().m_deco_waitingUntilAllDone) {\r
+ wxGetApp().m_deco_waitingUntilAllDone = false;\r
+ wxGetApp().m_deco_semAllDone.Post();\r
+ }\r
+ }\r
+}\r
+\r
+void *OPJDecoThread::Entry()\r
+{\r
+\r
+ wxString text;\r
+\r
+ srand(GetId());\r
+ int m_countnum = rand() % 9;\r
+ text.Printf(wxT("Deco thread 0x%lx started (priority = %u, time = %d)."),\r
+ GetId(), GetPriority(), m_countnum);\r
+ WriteText(text);\r
+ // wxLogMessage(text); -- test wxLog thread safeness\r
+\r
+ //wxBusyCursor wait;\r
+ //wxBusyInfo wait(wxT("Decoding image ..."));\r
+\r
+\r
+ /*for (m_count = 0; m_count < m_countnum; m_count++) {\r
+ // check if we were asked to exit\r
+ if ( TestDestroy() )\r
+ break;\r
+\r
+ text.Printf(wxT("[%u] Deco thread 0x%lx here."), m_count, GetId());\r
+ WriteText(text);\r
+\r
+ // wxSleep() can't be called from non-GUI thread!\r
+ wxThread::Sleep(10);\r
+ }*/\r
+\r
+ wxBitmap bitmap( 100, 100 );\r
+ wxImage image = bitmap.ConvertToImage();\r
+ image.Destroy();\r
+\r
+ WriteText(m_canvas->m_fname.GetFullPath());\r
+\r
+ if (!image.LoadFile(m_canvas->m_fname.GetFullPath(), wxBITMAP_TYPE_ANY), 0) {\r
+ wxLogError(wxT("Can't load image"));\r
+ return NULL;\r
+ }\r
+\r
+ m_canvas->m_image = wxBitmap(image);\r
+ m_canvas->Refresh();\r
+ m_canvas->SetScrollbars(20, 20, (int)(0.5 + (double) image.GetWidth() / 20.0), (int)(0.5 + (double) image.GetHeight() / 20.0));\r
+\r
+ text.Printf(wxT("Deco thread 0x%lx finished."), GetId());\r
+ WriteText(text);\r
+ // wxLogMessage(text); -- test wxLog thread safeness\r
+\r
+ return NULL;\r
+}\r
+\r
+/////////////////////////////////////////////////////////////////////\r
+// Parsing thread class\r
+/////////////////////////////////////////////////////////////////////\r
+\r
+OPJParseThread::OPJParseThread(OPJMarkerTree *tree, wxTreeItemId parentid)\r
+ : wxThread()\r
+{\r
+ m_count = 0;\r
+ m_tree = tree;\r
+ m_parentid = parentid;\r
+}\r
+\r
+void OPJParseThread::WriteText(const wxString& text)\r
+{\r
+ wxString msg;\r
+\r
+ // before doing any GUI calls we must ensure that this thread is the only\r
+ // one doing it!\r
+\r
+ wxMutexGuiEnter();\r
+\r
+ msg << text;\r
+ m_tree->WriteText(msg);\r
+\r
+ wxMutexGuiLeave();\r
+}\r
+\r
+void OPJParseThread::OnExit()\r
+{\r
+ wxCriticalSectionLocker locker(wxGetApp().m_parse_critsect);\r
+\r
+ wxArrayThread& threads = wxGetApp().m_parse_threads;\r
+ threads.Remove(this);\r
+\r
+ if ( threads.IsEmpty() )\r
+ {\r
+ // signal the main thread that there are no more threads left if it is\r
+ // waiting for us\r
+ if ( wxGetApp().m_parse_waitingUntilAllDone )\r
+ {\r
+ wxGetApp().m_parse_waitingUntilAllDone = false;\r
+\r
+ wxGetApp().m_parse_semAllDone.Post();\r
+ }\r
+ }\r
+}\r
+\r
+void *OPJParseThread::Entry()\r
+{\r
+\r
+ wxString text;\r
+\r
+ srand( GetId() );\r
+ int m_countnum = rand() % 9;\r
+ text.Printf(wxT("Parse thread 0x%lx started (priority = %u, time = %d)."),\r
+ GetId(), GetPriority(), m_countnum);\r
+ WriteText(text);\r
+ // wxLogMessage(text); -- test wxLog thread safeness\r
+\r
+ //wxBusyCursor wait;\r
+ //wxBusyInfo wait(wxT("Decoding image ..."));\r
+\r
+\r
+ /*for ( m_count = 0; m_count < m_countnum; m_count++ )\r
+ {\r
+ // check if we were asked to exit\r
+ if ( TestDestroy() )\r
+ break;\r
+\r
+ text.Printf(wxT("[%u] Parse thread 0x%lx here."), m_count, GetId());\r
+ WriteText(text);\r
+\r
+ // wxSleep() can't be called from non-GUI thread!\r
+ wxThread::Sleep(10);\r
+ }*/\r
+\r
+\r
+ LoadFile(m_tree->m_fname);\r
+\r
+ text.Printf(wxT("Parse thread 0x%lx finished."), GetId());\r
+ WriteText(text);\r
+ // wxLogMessage(text); -- test wxLog thread safeness\r
+\r
+ return NULL;\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2007, Digital Signal Processing Laboratory, Università degli studi di Perugia (UPG), Italy\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * 1. Redistributions of source code must retain the above copyright\r
+ * notice, this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ * notice, this list of conditions and the following disclaimer in the\r
+ * documentation and/or other materials provided with the distribution.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'\r
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\r
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
+ * POSSIBILITY OF SUCH DAMAGE.\r
+ */\r
+/////////////////////////////////////////////////////////////////////////////\r
+// Name: sashtest.h\r
+// Purpose: Layout window/sash sample\r
+// Author: Julian Smart\r
+// Modified by:\r
+// Created: 04/01/98\r
+// RCS-ID: $Id: sashtest.h,v 1.5 2005/06/02 12:04:24 JS Exp $\r
+// Copyright: (c) Julian Smart\r
+// Licence: wxWindows license\r
+/////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r
+// Name: treectrl.h\r
+// Purpose: wxTreeCtrl sample\r
+// Author: Julian Smart\r
+// Modified by:\r
+// Created: 04/01/98\r
+// RCS-ID: $Id: treetest.h,v 1.50 2006/11/04 11:26:51 VZ Exp $\r
+// Copyright: (c) Julian Smart\r
+// Licence: wxWindows license\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+#ifndef __OPJ_VIEWER_H__\r
+#define __OPJ_VIEWER_H__\r
+\r
+// For compilers that support precompilation, includes "wx/wx.h".\r
+#include "wx/wxprec.h"\r
+\r
+#ifdef __BORLANDC__\r
+#pragma hdrstop\r
+#endif\r
+\r
+#ifndef WX_PRECOMP\r
+#include "wx/wx.h"\r
+#include "wx/mdi.h"\r
+#endif\r
+\r
+#include "wx/toolbar.h"\r
+#include "wx/laywin.h"\r
+#include "wx/treectrl.h"\r
+\r
+#include "icon1.xpm"\r
+#include "icon2.xpm"\r
+#include "icon3.xpm"\r
+#include "icon4.xpm"\r
+#include "icon5.xpm"\r
+\r
+#include "wx/filedlg.h"\r
+#include "wx/toolbar.h"\r
+#include <wx/filename.h>\r
+#include <wx/busyinfo.h>\r
+#include <wx/cmdline.h>\r
+#include <wx/file.h>\r
+#include "wx/notebook.h"\r
+\r
+#include "libopenjpeg\openjpeg.h"\r
+\r
+#include "imagj2k.h"\r
+#include "imagjp2.h"\r
+#include "imagmj2.h"\r
+\r
+#define USE_GENERIC_TREECTRL 0\r
+\r
+#if USE_GENERIC_TREECTRL\r
+#include "wx/generic/treectlg.h"\r
+#ifndef wxTreeCtrl\r
+#define wxTreeCtrl wxGenericTreeCtrl\r
+#define sm_classwxTreeCtrl sm_classwxGenericTreeCtrl\r
+#endif\r
+#endif\r
+\r
+#define OPJ_APPLICATION_NAME wxT("OpenJPEG Viewer")\r
+#define OPJ_APPLICATION_VERSION wxT("0.1 alpha")\r
+#define OPJ_APPLICATION_TITLEBAR OPJ_APPLICATION_NAME wxT(" ") OPJ_APPLICATION_VERSION\r
+#define OPJ_APPLICATION_COPYRIGHT wxT("(C) 2007, Giuseppe Baruffa")\r
+\r
+#define OPJ_CANVAS_BORDER 10\r
+#define OPJ_CANVAS_COLOUR *wxWHITE\r
+\r
+class OPJDecoThread;\r
+class OPJParseThread;\r
+WX_DEFINE_ARRAY_PTR(wxThread *, wxArrayThread);\r
+class OPJChildFrame;\r
+\r
+//////////////////////////////////\r
+// this is our main application //\r
+//////////////////////////////////\r
+class OPJViewerApp: public wxApp\r
+{\r
+ // public methods and variables\r
+ public:\r
+\r
+ // class constructor\r
+ OPJViewerApp() { m_showImages = true; m_showButtons = false; }\r
+\r
+ // other methods\r
+ bool OnInit(void);\r
+ void SetShowImages(bool show) { m_showImages = show; }\r
+ bool ShowImages() const { return m_showImages; }\r
+ void ShowCmdLine(const wxCmdLineParser& parser);\r
+\r
+ // all the threads currently alive - as soon as the thread terminates, it's\r
+ // removed from the array\r
+ wxArrayThread m_deco_threads, m_parse_threads;\r
+\r
+ // crit section protects access to all of the arrays below\r
+ wxCriticalSection m_deco_critsect, m_parse_critsect;\r
+\r
+ // semaphore used to wait for the threads to exit, see OPJFrame::OnQuit()\r
+ wxSemaphore m_deco_semAllDone, m_parse_semAllDone;\r
+\r
+ // the last exiting thread should post to m_semAllDone if this is true\r
+ // (protected by the same m_critsect)\r
+ bool m_deco_waitingUntilAllDone, m_parse_waitingUntilAllDone;\r
+\r
+ // the list of all filenames written in the command line\r
+ wxArrayString m_filelist;\r
+\r
+ // private methods and variables\r
+ private:\r
+ bool m_showImages, m_showButtons;\r
+\r
+};\r
+\r
+DECLARE_APP(OPJViewerApp)\r
+\r
+///////////////////////////////////////////\r
+// this canvas is used to draw the image //\r
+///////////////////////////////////////////\r
+class OPJCanvas: public wxScrolledWindow\r
+{\r
+ // public methods and variables\r
+ public:\r
+\r
+ // class constructor\r
+ OPJCanvas(wxFileName fname, wxWindow *parent, const wxPoint& pos, const wxSize& size);\r
+\r
+ virtual void OnDraw(wxDC& dc);\r
+ void OnEvent(wxMouseEvent& event);\r
+ void WriteText(const wxString& text) { wxMutexGuiEnter(); wxLogMessage(text); wxMutexGuiLeave();}\r
+ OPJDecoThread *CreateDecoThread(void);\r
+\r
+ wxBitmap m_image;\r
+ wxFileName m_fname;\r
+\r
+ DECLARE_EVENT_TABLE()\r
+};\r
+\r
+///////////////////////////////////////////////////\r
+// the data associated to each tree leaf or node //\r
+///////////////////////////////////////////////////\r
+class OPJMarkerData : public wxTreeItemData\r
+{\r
+ // public methods and variables\r
+ public:\r
+\r
+ // class constructor\r
+ OPJMarkerData(const wxString& desc, const wxString& fname = wxT(""), wxFileOffset start = 0, wxFileOffset length = 0) : m_desc(desc), m_filestring(fname) { m_start = start; m_length = length; }\r
+\r
+ void ShowInfo(wxTreeCtrl *tree);\r
+ const wxChar *GetDesc1() const { return m_desc.c_str(); }\r
+ const wxChar *GetDesc2() const { return m_filestring.c_str(); }\r
+ wxFileOffset m_start, m_length;\r
+\r
+ // private methods and variables\r
+ private:\r
+ wxString m_desc;\r
+ wxString m_filestring;\r
+};\r
+\r
+\r
+class OPJMarkerTree : public wxTreeCtrl\r
+{\r
+public:\r
+ enum\r
+ {\r
+ TreeCtrlIcon_File,\r
+ TreeCtrlIcon_FileSelected,\r
+ TreeCtrlIcon_Folder,\r
+ TreeCtrlIcon_FolderSelected,\r
+ TreeCtrlIcon_FolderOpened\r
+ };\r
+\r
+ OPJMarkerTree() { };\r
+ OPJMarkerTree(wxWindow *parent, wxFileName fname, wxString name, const wxWindowID id,\r
+ const wxPoint& pos, const wxSize& size,\r
+ long style);\r
+ virtual ~OPJMarkerTree(){};\r
+ OPJParseThread *CreateParseThread(wxTreeItemId parentid = 0x00);\r
+ void WriteText(const wxString& text) { wxMutexGuiEnter(); wxLogMessage(text); wxMutexGuiLeave(); }\r
+\r
+ wxFileName m_fname;\r
+ wxTextCtrl *m_peektextCtrl;\r
+\r
+ /*void OnBeginDrag(wxTreeEvent& event);\r
+ void OnBeginRDrag(wxTreeEvent& event);\r
+ void OnEndDrag(wxTreeEvent& event);*/\r
+ /*void OnBeginLabelEdit(wxTreeEvent& event);\r
+ void OnEndLabelEdit(wxTreeEvent& event);*/\r
+ /*void OnDeleteItem(wxTreeEvent& event);*/\r
+ /*void OnContextMenu(wxContextMenuEvent& event);*/\r
+ /*void OnItemMenu(wxTreeEvent& event);*/\r
+ /*void OnGetInfo(wxTreeEvent& event);\r
+ void OnSetInfo(wxTreeEvent& event);*/\r
+ /*void OnItemExpanded(wxTreeEvent& event);*/\r
+ void OnItemExpanding(wxTreeEvent& event);\r
+ /*void OnItemCollapsed(wxTreeEvent& event);\r
+ void OnItemCollapsing(wxTreeEvent& event);*/\r
+ void OnSelChanged(wxTreeEvent& event);\r
+ /*void OnSelChanging(wxTreeEvent& event);*/\r
+ /*void OnTreeKeyDown(wxTreeEvent& event);*/\r
+ /*void OnItemActivated(wxTreeEvent& event);*/\r
+ /*void OnItemRClick(wxTreeEvent& event);*/\r
+ /*void OnRMouseDown(wxMouseEvent& event);\r
+ void OnRMouseUp(wxMouseEvent& event);\r
+ void OnRMouseDClick(wxMouseEvent& event);*/\r
+ /*void GetItemsRecursively(const wxTreeItemId& idParent,\r
+ wxTreeItemIdValue cookie = 0);*/\r
+\r
+ void CreateImageList(int size = 16);\r
+ void CreateButtonsImageList(int size = 11);\r
+\r
+ /*void AddTestItemsToTree(size_t numChildren, size_t depth);*/\r
+ /*void DoSortChildren(const wxTreeItemId& item, bool reverse = false)\r
+ { m_reverseSort = reverse; wxTreeCtrl::SortChildren(item); }*/\r
+ /*void DoEnsureVisible() { if (m_lastItem.IsOk()) EnsureVisible(m_lastItem); }*/\r
+ /*void DoToggleIcon(const wxTreeItemId& item);*/\r
+ /*void ShowMenu(wxTreeItemId id, const wxPoint& pt);*/\r
+\r
+ int ImageSize(void) const { return m_imageSize; }\r
+\r
+ void SetLastItem(wxTreeItemId id) { m_lastItem = id; }\r
+\r
+protected:\r
+ /*virtual int OnCompareItems(const wxTreeItemId& i1, const wxTreeItemId& i2);*/\r
+\r
+ // is this the test item which we use in several event handlers?\r
+ /*bool IsTestItem(const wxTreeItemId& item)\r
+ {\r
+ // the test item is the first child folder\r
+ return GetItemParent(item) == GetRootItem() && !GetPrevSibling(item);\r
+ }*/\r
+\r
+private:\r
+ /*void AddItemsRecursively(const wxTreeItemId& idParent,\r
+ size_t nChildren,\r
+ size_t depth,\r
+ size_t folder);*/\r
+\r
+ void LogEvent(const wxChar *name, const wxTreeEvent& event);\r
+\r
+ int m_imageSize; // current size of images\r
+ bool m_reverseSort; // flag for OnCompareItems\r
+ wxTreeItemId m_lastItem, // for OnEnsureVisible()\r
+ m_draggedItem; // item being dragged right now\r
+\r
+ // NB: due to an ugly wxMSW hack you _must_ use DECLARE_DYNAMIC_CLASS()\r
+ // if you want your overloaded OnCompareItems() to be called.\r
+ // OTOH, if you don't want it you may omit the next line - this will\r
+ // make default (alphabetical) sorting much faster under wxMSW.\r
+ DECLARE_DYNAMIC_CLASS(OPJMarkerTree)\r
+ DECLARE_EVENT_TABLE()\r
+};\r
+\r
+// this hash map stores all the trees of currently opened images, with an integer key\r
+WX_DECLARE_HASH_MAP(int, OPJMarkerTree*, wxIntegerHash, wxIntegerEqual, OPJMarkerTreeHash);\r
+\r
+// this hash map stores all the children of currently opened images, with an integer key\r
+WX_DECLARE_HASH_MAP(int, OPJChildFrame*, wxIntegerHash, wxIntegerEqual, OPJChildFrameHash);\r
+\r
+// Define a new frame\r
+class OPJFrame: public wxMDIParentFrame\r
+{\r
+ public:\r
+\r
+ OPJFrame(wxWindow *parent, const wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, const long style);\r
+\r
+ ~OPJFrame(void);\r
+ void OnSize(wxSizeEvent& event);\r
+ void OnAbout(wxCommandEvent& WXUNUSED(event));\r
+ void OnFileOpen(wxCommandEvent& WXUNUSED(event));\r
+ void OnQuit(wxCommandEvent& WXUNUSED(event));\r
+ void OnToggleWindow(wxCommandEvent& WXUNUSED(event));\r
+ void OnSashDrag(wxSashEvent& event);\r
+ void OpenFiles(wxArrayString paths, wxArrayString filenames);\r
+ void OnNotebook(wxNotebookEvent& event);\r
+\r
+ OPJMarkerTreeHash m_treehash;\r
+ OPJChildFrameHash m_childhash;\r
+ wxSashLayoutWindow* markerTreeWindow;\r
+ wxSashLayoutWindow* loggingWindow;\r
+ void Resize(int number);\r
+ wxNotebook *m_bookCtrl;\r
+ wxNotebook *m_bookCtrlbottom;\r
+ wxTextCtrl *m_textCtrlbrowse;\r
+\r
+ private:\r
+ void TogStyle(int id, long flag);\r
+\r
+ void DoSort(bool reverse = false);\r
+\r
+ wxPanel *m_panel;\r
+ wxTextCtrl *m_textCtrl;\r
+\r
+ void DoSetBold(bool bold = true);\r
+\r
+protected:\r
+ wxSashLayoutWindow* m_topWindow;\r
+ wxSashLayoutWindow* m_leftWindow2;\r
+\r
+DECLARE_EVENT_TABLE()\r
+};\r
+\r
+class OPJChildFrame: public wxMDIChildFrame\r
+{\r
+ public:\r
+ OPJCanvas *m_canvas;\r
+ OPJChildFrame(OPJFrame *parent, wxFileName fname, int winnumber, const wxString& title, const wxPoint& pos, const wxSize& size, const long style);\r
+ ~OPJChildFrame(void);\r
+ void OnActivate(wxActivateEvent& event);\r
+ /*void OnQuit(wxCommandEvent& WXUNUSED(event));*/\r
+ void OnClose(wxCloseEvent& event);\r
+ void OnGotFocus(wxFocusEvent& event);\r
+ /*void OnLostFocus(wxFocusEvent& event);*/\r
+ OPJFrame *m_frame;\r
+ wxFileName m_fname;\r
+ int m_winnumber;\r
+\r
+DECLARE_EVENT_TABLE()\r
+};\r
+\r
+#define SASHTEST_QUIT wxID_EXIT\r
+#define SASHTEST_NEW_WINDOW 2\r
+#define SASHTEST_REFRESH 3\r
+#define SASHTEST_CHILD_QUIT 4\r
+#define SASHTEST_ABOUT wxID_ABOUT\r
+#define SASHTEST_TOGGLE_WINDOW 6\r
+\r
+#define ID_WINDOW_TOP 100\r
+#define ID_WINDOW_LEFT1 101\r
+#define ID_WINDOW_LEFT2 102\r
+#define ID_WINDOW_BOTTOM 103\r
+\r
+// menu and control ids\r
+enum\r
+{\r
+ TreeTest_Quit = wxID_EXIT,\r
+ TreeTest_About = wxID_ABOUT,\r
+ TreeTest_TogButtons = wxID_HIGHEST,\r
+ TreeTest_TogTwist,\r
+ TreeTest_TogLines,\r
+ TreeTest_TogEdit,\r
+ TreeTest_TogHideRoot,\r
+ TreeTest_TogRootLines,\r
+ TreeTest_TogBorder,\r
+ TreeTest_TogFullHighlight,\r
+ TreeTest_SetFgColour,\r
+ TreeTest_SetBgColour,\r
+ TreeTest_ResetStyle,\r
+ TreeTest_Highlight,\r
+ TreeTest_Dump,\r
+ TreeTest_DumpSelected,\r
+ TreeTest_Count,\r
+ TreeTest_CountRec,\r
+ TreeTest_Sort,\r
+ TreeTest_SortRev,\r
+ TreeTest_SetBold,\r
+ TreeTest_ClearBold,\r
+ TreeTest_Rename,\r
+ TreeTest_Delete,\r
+ TreeTest_DeleteChildren,\r
+ TreeTest_DeleteAll,\r
+ TreeTest_Recreate,\r
+ TreeTest_ToggleImages,\r
+ TreeTest_ToggleButtons,\r
+ TreeTest_SetImageSize,\r
+ TreeTest_ToggleSel,\r
+ TreeTest_CollapseAndReset,\r
+ TreeTest_EnsureVisible,\r
+ TreeTest_AddItem,\r
+ TreeTest_InsertItem,\r
+ TreeTest_IncIndent,\r
+ TreeTest_DecIndent,\r
+ TreeTest_IncSpacing,\r
+ TreeTest_DecSpacing,\r
+ TreeTest_ToggleIcon,\r
+ TreeTest_Select,\r
+ TreeTest_Unselect,\r
+ TreeTest_SelectRoot,\r
+ TreeTest_Ctrl = 1000,\r
+ BOTTOM_NOTEBOOK_ID,\r
+ LEFT_NOTEBOOK_ID\r
+};\r
+\r
+class OPJDecoThread : public wxThread\r
+{\r
+public:\r
+ OPJDecoThread(OPJCanvas *canvas);\r
+\r
+ // thread execution starts here\r
+ virtual void *Entry();\r
+\r
+ // called when the thread exits - whether it terminates normally or is\r
+ // stopped with Delete() (but not when it is Kill()ed!)\r
+ virtual void OnExit();\r
+\r
+ // write something to the text control\r
+ void WriteText(const wxString& text);\r
+\r
+public:\r
+ unsigned m_count;\r
+ OPJCanvas *m_canvas;\r
+};\r
+\r
+class OPJParseThread : public wxThread\r
+{\r
+public:\r
+ OPJParseThread(OPJMarkerTree *tree, wxTreeItemId parentid = 0x00);\r
+\r
+ // thread execution starts here\r
+ virtual void *Entry();\r
+\r
+ // called when the thread exits - whether it terminates normally or is\r
+ // stopped with Delete() (but not when it is Kill()ed!)\r
+ virtual void OnExit();\r
+\r
+ // write something to the text control\r
+ void WriteText(const wxString& text);\r
+ void LoadFile(wxFileName fname);\r
+ void ParseJ2KFile(wxFile *m_file, wxFileOffset offset, wxFileOffset length, wxTreeItemId parentid);\r
+ void ParseJP2File(wxFile *fileid, wxFileOffset filepoint, wxFileOffset filelimit, wxTreeItemId parentid);\r
+\r
+ unsigned m_count;\r
+ OPJMarkerTree *m_tree;\r
+ wxTreeItemId m_parentid;\r
+\r
+private:\r
+ int jpeg2000parse(wxFile *fileid, wxFileOffset filepoint, wxFileOffset filelimit,\r
+ wxTreeItemId parentid, int level, char *scansign, unsigned long int *scanpoint);\r
+ int box_handler_function(int boxtype, wxFile *fileid, wxFileOffset filepoint, wxFileOffset filelimit,\r
+ wxTreeItemId parentid, int level, char *scansign, unsigned long int *scanpoint);\r
+\r
+};\r
+\r
+#endif //__OPJ_VIEWER_H__\r
--- /dev/null
+OPJViewer16 ICON OPJViewer.ico\r
+#include "wx/msw/wx.rc"
\ No newline at end of file
--- /dev/null
+/* XPM */\r
+static char *OPJViewer16[] = {\r
+/* columns rows colors chars-per-pixel */\r
+"16 16 4 1",\r
+" c black",\r
+". c #800000",\r
+"X c red",\r
+"o c None",\r
+/* pixels */\r
+"oooooooooooooooo",\r
+"ooo.XXXXoooooooo",\r
+"ooXXoo .Xooooooo",\r
+"o..oooo .ooooooo",\r
+"oX.oooo ooooooo",\r
+"oX.oooo .ooooooo",\r
+"oXXoooo .ooooooo",\r
+"o.XXoo .oooooooo",\r
+"oo.XXXXooooooooo",\r
+"ooooooooo.Xo .oo",\r
+"ooooooooo X. ooo",\r
+"oooooooooo...ooo",\r
+"oooooooooo XXooo",\r
+"oooooooooo .Xooo",\r
+"oooooooooooooooo",\r
+"oooooooooooooooo"\r
+};\r
--- /dev/null
+/* XPM */
+static char *icon1_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"32 32 41 1",
+"> c #97C4E7",
+"# c #4381AA",
+"d c #FFFFFF",
+"< c #71B2DE",
+"+ c #538BB1",
+"& c #D1E5F5",
+"q c #63B3DE",
+"6 c #F1F4F7",
+"* c #CAE1F3",
+"y c #7AC4E5",
+"= c #C3DDF1",
+"X c #74A1BD",
+"- c #BCD9EF",
+"5 c #619BC4",
+"3 c #E6EAF1",
+"2 c #4B8EBF",
+"o c #6B97B6",
+". c #4B82A8",
+" c None",
+"w c #54A6D8",
+"1 c #71A8D1",
+", c #85BBE2",
+"t c #EFF6FC",
+"7 c #DEEDF8",
+"@ c #4388B4",
+"a c #F7FBFD",
+"$ c #D7E0E9",
+"r c #FAFCFE",
+"4 c #DAEAF7",
+"e c #E9F3FA",
+"0 c #76BAE2",
+"% c #7FA6C0",
+"s c #FDFDFE",
+"O c #5896BE",
+"p c #B6D5EE",
+"8 c #87ABC3",
+": c #A5CCEA",
+"9 c #E5F0F9",
+"; c #AFD1EC",
+"i c #F4F9FD",
+"u c #8FB0C3",
+/* pixels */
+" ",
+" ",
+" ",
+" ",
+" ",
+" .XXXooOO++@#$ ",
+" %&*=-;:>>,<123 ",
+" %4&*=-;:>>,1>56 ",
+" %74&*=-;:>>1*>56 ",
+" 89700qqqqwq1e*>X ",
+" 8e974&*=-;:1re*>8 ",
+" 8te974&*=-;11111# ",
+" 8tty000qqqqqww>,+ ",
+" uitte974&*=-p:>>+ ",
+" uaitte974&*=-p:>O ",
+" uaayyyy000qqqqp:O ",
+" uraaitte974&*=-po ",
+" urraaitte974&*=-o ",
+" usryyyyyyy000q*=X ",
+" ussrraaitte974&*X ",
+" udssrraaitte974&X ",
+" uddyyyyyyyyyy074% ",
+" udddssrraaitte97% ",
+" uddddssrraaitte9% ",
+" udddddssrraaitte8 ",
+" uddddddssrraaitt8 ",
+" uuuuuuuuuuuuuu88u ",
+" ",
+" ",
+" ",
+" ",
+" "
+};
--- /dev/null
+/* XPM */
+static char *icon2_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"32 32 15 1",
+". c Black",
+"O c #97C4E7",
+"$ c #63B3DE",
+"@ c #CAE1F3",
+"; c #7AC4E5",
+"* c #74A1BD",
+"+ c #619BC4",
+"o c #4B8EBF",
+" c None",
+"% c #54A6D8",
+"= c #FAFCFE",
+"& c #E9F3FA",
+"# c #76BAE2",
+"X c #C00000",
+"- c #87ABC3",
+/* pixels */
+" ",
+" ",
+" ",
+" ",
+" ",
+" ............. ",
+" .XXXXXXXXXX.o. ",
+" .XXXXXXXXXX.O+. ",
+" .XXXXXXXXXX.@O+. ",
+" .XX##$$$$%$.&@O* ",
+" .XXXXXXXXXX.=&@O- ",
+" .XXXXXXXXXX...... ",
+" .XX;###$$$$$%%XX. ",
+" .XXXXXXXXXXXXXXX. ",
+" .XXXXXXXXXXXXXXX. ",
+" .XX;;;;###$$$$XX. ",
+" .XXXXXXXXXXXXXXX. ",
+" .XXXXXXXXXXXXXXX. ",
+" .XX;;;;;;;###$XX. ",
+" .XXXXXXXXXXXXXXX. ",
+" .XXXXXXXXXXXXXXX. ",
+" .XX;;;;;;;;;;#XX. ",
+" .XXXXXXXXXXXXXXX. ",
+" .XXXXXXXXXXXXXXX. ",
+" .XXXXXXXXXXXXXXX. ",
+" .XXXXXXXXXXXXXXX. ",
+" ................. ",
+" ",
+" ",
+" ",
+" ",
+" "
+};
--- /dev/null
+/* XPM */
+static char *icon3_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"32 32 41 1",
+"6 c #EDF2FB",
+"- c #AAC1E8",
+": c #B9CDED",
+"X c #295193",
+", c #C6D6F0",
+"a c #4A7CCE",
+"u c #779DDB",
+"y c #7FA2DD",
+"$ c #3263B4",
+"5 c #EAF0FA",
+". c #2D59A3",
+"o c #6E96D8",
+"* c #356AC1",
+"r c #F7F9FD",
+"> c #BED0EE",
+"3 c #E1E9F7",
+"7 c #F0F5FC",
+"< c #CBD9F1",
+"2 c #DAE5F6",
+"# c #3161B1",
+" c None",
+"0 c #FDFEFF",
+"= c #9FB9E5",
+"e c #AEC5EA",
+"t c #89A9DF",
+"q c #98B5E4",
+"p c #5584D1",
+"d c #3A70CA",
+"@ c #305FAC",
+"i c #5D89D3",
+"1 c #D2DFF4",
+"% c #3366B9",
+"9 c #FAFCFE",
+"8 c #F5F8FD",
+"s c #4075CC",
+"O c #638ED5",
+"w c #90AFE2",
+"& c #3467BC",
+"+ c #2F5DA9",
+"; c #B3C8EB",
+"4 c #E5EDF9",
+/* pixels */
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ......X ",
+" .oooooO+ ",
+" .ooooooo. ",
+" .+@@@##$%%&&&&&****. ",
+" .=-;:>,<12345678900. ",
+" .q=-;:>,<1234567890. ",
+" .wq=-e:>,<12345678r. ",
+" .twq=-e:>,<12345678. ",
+" .ytwq=-e:>,<1234567. ",
+" .uytwq=-e:>,<123456. ",
+" .ouytwq=-e:>,<12345. ",
+" .Oouytwq=-e;>,<1234. ",
+" .iOouytwq=-e;>,<123. ",
+" .piOouytwq=-e;>,<12. ",
+" .apiOouytwq=-e;>,<1. ",
+" .sapiOouytwq=-e;>,<. ",
+" .dsapiOouytwq=-e;>,. ",
+" ...................# ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" "
+};
--- /dev/null
+/* XPM */
+static char *icon4_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"32 32 5 1",
+". c Black",
+"o c #8399B4",
+"X c #8DA0B9",
+" c None",
+"O c #800000",
+/* pixels */
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ....... ",
+" .XXXXXo. ",
+" .XXXXXXX. ",
+" .................... ",
+" .OOOOOOOOOOOOOOOOOO. ",
+" .OOOOOOOOOOOOOOOOOO. ",
+" .OOOOOOOOOOOOOOOOOO. ",
+" .OOOOOOOOOOOOOOOOOO. ",
+" .OOOOOOOOOOOOOOOOOO. ",
+" .OOOOOOOOOOOOOOOOOO. ",
+" .OOOOOOOOOOOOOOOOOO. ",
+" .OOOOOOOOOOOOOOOOOO. ",
+" .OOOOOOOOOOOOOOOOOO. ",
+" .OOOOOOOOOOOOOOOOOO. ",
+" .OOOOOOOOOOOOOOOOOO. ",
+" .OOOOOOOOOOOOOOOOOO. ",
+" .OOOOOOOOOOOOOOOOOO. ",
+" .................... ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" "
+};
--- /dev/null
+/* XPM */
+static char *icon5_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"32 32 41 1",
+"0 c #AAC1E8",
+"q c #B9CDED",
+"X c #295193",
+"e c #C6D6F0",
+"a c #4A7CCE",
+"& c #779DDB",
+"* c #7FA2DD",
+"2 c #EAF0FA",
+"@ c #2D59A3",
+"o c #6E96D8",
+"y c #356AC1",
+"d c #214279",
+"w c #BED0EE",
+"= c #85A7DF",
+"< c #E1E9F7",
+"3 c #F0F5FC",
+"s c #CBD9F1",
+", c #DAE5F6",
+"7 c #3161B1",
+" c None",
+". c #274D8B",
+"6 c #FDFEFF",
+"i c #E7EEF9",
+"9 c #9FB9E5",
+"- c #89A9DF",
+"8 c #98B5E4",
+"$ c #5584D1",
+"+ c #3569BF",
+"% c #305FAC",
+"O c #5D89D3",
+"> c #D2DFF4",
+"p c #3366B9",
+"5 c #FAFCFE",
+"4 c #F5F8FD",
+"t c #4075CC",
+"u c #638ED5",
+"r c #CEDCF2",
+"; c #90AFE2",
+"# c #2F5DA9",
+": c #B3C8EB",
+"1 c #E5EDF9",
+/* pixels */
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ......X ",
+" XoooooO. ",
+" Xoooooo+. ",
+" Xooooooo@XXXXXXXXXX# ",
+" Xoooooooooooooooooo# ",
+" Xoooooooooooooooooo# ",
+" Xoo$################### ",
+" Xoo%O&*=-;:>,<123445667 ",
+" XooX890:qwer>,<123445q# ",
+" Xoty;890:qwer>,<12344# ",
+" Xo%u-;890:qwer>,<i234# ",
+" XoX&*-;890:qwer>,<i2r# ",
+" Xtpo&*-;890:qwer>,<i# ",
+" X%auo&*-;890:qwer>,<# ",
+" XX$Ouo&*-;890:qwer>s# ",
+" d%a$Ouo&*-;890:qwer# ",
+" d+ta$Ouo&*-;890:qwe# ",
+" d..................# ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" "
+};
--- /dev/null
+/*\r
+ * Copyright (c) 2007, Digital Signal Processing Laboratory, Università degli studi di Perugia (UPG), Italy\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * 1. Redistributions of source code must retain the above copyright\r
+ * notice, this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ * notice, this list of conditions and the following disclaimer in the\r
+ * documentation and/or other materials provided with the distribution.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'\r
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\r
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
+ * POSSIBILITY OF SUCH DAMAGE.\r
+ */\r
+/////////////////////////////////////////////////////////////////////////////\r
+// Name: imagj2k.cpp\r
+// Purpose: wxImage JPEG 2000 codestream handler\r
+// Author: Giuseppe Baruffa - based on imagjpeg.cpp, Vaclav Slavik\r
+// RCS-ID: $Id: imagj2k.cpp,v 0.00 2007/02/08 23:59:00 MW Exp $\r
+// Copyright: (c) Giuseppe Baruffa\r
+// Licence: wxWindows licence\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+// For compilers that support precompilation, includes "wx.h".\r
+#include "wx/wxprec.h"\r
+\r
+#ifdef __BORLANDC__\r
+ #pragma hdrstop\r
+#endif\r
+\r
+#if wxUSE_IMAGE && wxUSE_LIBOPENJPEG\r
+\r
+#include "imagj2k.h"\r
+\r
+#ifndef WX_PRECOMP\r
+ #include "wx/log.h"\r
+ #include "wx/app.h"\r
+ #include "wx/intl.h"\r
+ #include "wx/bitmap.h"\r
+ #include "wx/module.h"\r
+#endif\r
+\r
+\r
+#include "libopenjpeg/openjpeg.h"\r
+\r
+\r
+#include "wx/filefn.h"\r
+#include "wx/wfstream.h"\r
+\r
+// ----------------------------------------------------------------------------\r
+// types\r
+// ----------------------------------------------------------------------------\r
+\r
+\r
+//-----------------------------------------------------------------------------\r
+// wxJ2KHandler\r
+//-----------------------------------------------------------------------------\r
+\r
+IMPLEMENT_DYNAMIC_CLASS(wxJ2KHandler,wxImageHandler)\r
+\r
+#if wxUSE_STREAMS\r
+\r
+//------------- JPEG 2000 Data Source Manager\r
+\r
+#define J2K_CFMT 0\r
+#define JP2_CFMT 1\r
+#define JPT_CFMT 2\r
+#define MJ2_CFMT 3\r
+#define PXM_DFMT 0\r
+#define PGX_DFMT 1\r
+#define BMP_DFMT 2\r
+#define YUV_DFMT 3\r
+\r
+#define MAX_MESSAGE_LEN 200\r
+\r
+/* sample error callback expecting a FILE* client object */\r
+void j2k_error_callback(const char *msg, void *client_data) {\r
+ char m_msg[MAX_MESSAGE_LEN];\r
+ int message_len = strlen(msg) - 1;\r
+ if (msg[message_len] != '\n')\r
+ message_len = MAX_MESSAGE_LEN;\r
+ sprintf(m_msg, "[ERROR] %.*s", message_len, msg);\r
+ wxMutexGuiEnter();\r
+ wxLogMessage(m_msg);\r
+ wxMutexGuiLeave();\r
+}\r
+/* sample warning callback expecting a FILE* client object */\r
+void j2k_warning_callback(const char *msg, void *client_data) {\r
+ char m_msg[MAX_MESSAGE_LEN];\r
+ int message_len = strlen(msg) - 1;\r
+ if (msg[message_len] != '\n')\r
+ message_len = MAX_MESSAGE_LEN;\r
+ sprintf(m_msg, "[WARNING] %.*s", message_len, msg);\r
+ wxMutexGuiEnter();\r
+ wxLogMessage(m_msg);\r
+ wxMutexGuiLeave();\r
+}\r
+/* sample debug callback expecting no client object */\r
+void j2k_info_callback(const char *msg, void *client_data) {\r
+ char m_msg[MAX_MESSAGE_LEN];\r
+ int message_len = strlen(msg) - 1;\r
+ if (msg[message_len] != '\n')\r
+ message_len = MAX_MESSAGE_LEN;\r
+ sprintf(m_msg, "[INFO] %.*s", message_len, msg);\r
+ wxMutexGuiEnter();\r
+ wxLogMessage(m_msg);\r
+ wxMutexGuiLeave();\r
+}\r
+\r
+// load the j2k codestream\r
+bool wxJ2KHandler::LoadFile(wxImage *image, wxInputStream& stream, bool verbose, int index)\r
+{\r
+ opj_dparameters_t parameters; /* decompression parameters */\r
+ opj_event_mgr_t event_mgr; /* event manager */\r
+ opj_image_t *opjimage = NULL;\r
+ FILE *fsrc = NULL;\r
+ unsigned char *src = NULL;\r
+ unsigned char *ptr;\r
+ int file_length;\r
+ int shiftbpp;\r
+\r
+ // destroy the image\r
+ image->Destroy();\r
+\r
+ /* handle to a decompressor */\r
+ opj_dinfo_t* dinfo = NULL; \r
+ opj_cio_t *cio = NULL;\r
+\r
+ /* configure the event callbacks (not required) */\r
+ memset(&event_mgr, 0, sizeof(opj_event_mgr_t));\r
+ event_mgr.error_handler = j2k_error_callback;\r
+ event_mgr.warning_handler = j2k_warning_callback;\r
+ event_mgr.info_handler = j2k_info_callback;\r
+\r
+ /* set decoding parameters to default values */\r
+ opj_set_default_decoder_parameters(¶meters);\r
+\r
+ /* prepare parameters */\r
+ parameters.decod_format = J2K_CFMT;\r
+ parameters.cod_format = BMP_DFMT;\r
+\r
+ /* JPWL only */\r
+#ifdef USE_JPWL\r
+ parameters.jpwl_exp_comps = 3;\r
+ parameters.jpwl_max_tiles = 100;\r
+ parameters.jpwl_correct = true;\r
+#endif /* USE_JPWL */\r
+\r
+ /* get a decoder handle */\r
+ dinfo = opj_create_decompress(CODEC_J2K);\r
+\r
+ /* find length of the stream */\r
+ stream.SeekI(0, wxFromEnd);\r
+ file_length = (int) stream.TellI();\r
+\r
+ /* get data */\r
+ stream.SeekI(0, wxFromStart);\r
+ src = (unsigned char *) malloc(file_length);\r
+ stream.Read(src, file_length);\r
+\r
+ /* catch events using our callbacks and give a local context */\r
+ opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, stderr);\r
+\r
+ /* setup the decoder decoding parameters using user parameters */\r
+ opj_setup_decoder(dinfo, ¶meters);\r
+\r
+ /* open a byte stream */\r
+ cio = opj_cio_open((opj_common_ptr)dinfo, src, file_length);\r
+\r
+ /* decode the stream and fill the image structure */\r
+ opjimage = opj_decode(dinfo, cio);\r
+ if (!opjimage) {\r
+ wxMutexGuiEnter();\r
+ wxLogError("J2K: failed to decode image!");\r
+ wxMutexGuiLeave();\r
+ opj_destroy_decompress(dinfo);\r
+ opj_cio_close(cio);\r
+ opj_image_destroy(opjimage);\r
+ free(src);\r
+ return false;\r
+ }\r
+\r
+ // check image components\r
+ if ((opjimage->numcomps != 1) && (opjimage->numcomps != 3)) {\r
+ wxMutexGuiEnter();\r
+ wxLogError("J2K: weird number of components");\r
+ wxMutexGuiLeave();\r
+ opj_destroy_decompress(dinfo);\r
+ opj_cio_close(cio);\r
+ free(src);\r
+ return false;\r
+ }\r
+\r
+ // check image depth (only on the first one, for now)\r
+ shiftbpp = opjimage->comps[0].prec - 8;\r
+\r
+ // prepare image size\r
+ image->Create(opjimage->comps[0].w, opjimage->comps[0].h, true );\r
+\r
+ // access image raw data\r
+ image->SetMask( false );\r
+ ptr = image->GetData();\r
+\r
+ // RGB color picture\r
+ if (opjimage->numcomps == 3) {\r
+ int row, col;\r
+ int *r = opjimage->comps[0].data;\r
+ int *g = opjimage->comps[1].data;\r
+ int *b = opjimage->comps[2].data;\r
+ if (shiftbpp > 0) {\r
+ for (row = 0; row < opjimage->comps[0].h; row++) {\r
+ for (col = 0; col < opjimage->comps[0].w; col++) {\r
+ \r
+ *(ptr++) = (*(r++)) >> shiftbpp;\r
+ *(ptr++) = (*(g++)) >> shiftbpp;\r
+ *(ptr++) = (*(b++)) >> shiftbpp;\r
+\r
+ }\r
+ }\r
+ } else {\r
+ for (row = 0; row < opjimage->comps[0].h; row++) {\r
+ for (col = 0; col < opjimage->comps[0].w; col++) {\r
+ \r
+ *(ptr++) = *(r++);\r
+ *(ptr++) = *(g++);\r
+ *(ptr++) = *(b++);\r
+\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ // B/W picture\r
+ if (opjimage->numcomps == 1) {\r
+ int row, col;\r
+ int *y = opjimage->comps[0].data;\r
+ if (shiftbpp > 0) {\r
+ for (row = 0; row < opjimage->comps[0].h; row++) {\r
+ for (col = 0; col < opjimage->comps[0].w; col++) {\r
+ \r
+ *(ptr++) = (*(y)) >> shiftbpp;\r
+ *(ptr++) = (*(y)) >> shiftbpp;\r
+ *(ptr++) = (*(y++)) >> shiftbpp;\r
+\r
+ }\r
+ }\r
+ } else {\r
+ for (row = 0; row < opjimage->comps[0].h; row++) {\r
+ for (col = 0; col < opjimage->comps[0].w; col++) {\r
+ \r
+ *(ptr++) = *(y);\r
+ *(ptr++) = *(y);\r
+ *(ptr++) = *(y++);\r
+\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ wxMutexGuiEnter();\r
+ wxLogMessage(wxT("J2K: image loaded."));\r
+ wxMutexGuiLeave();\r
+\r
+ /* close openjpeg structs */\r
+ opj_destroy_decompress(dinfo);\r
+ opj_cio_close(cio);\r
+ opj_image_destroy(opjimage);\r
+ free(src);\r
+\r
+ if (!image->Ok())\r
+ return false;\r
+ else\r
+ return true;\r
+\r
+}\r
+\r
+// save the j2k codestream\r
+bool wxJ2KHandler::SaveFile( wxImage *image, wxOutputStream& stream, bool verbose )\r
+{\r
+ wxLogError(wxT("J2K: Couldn't save image -> not implemented."));\r
+ return false;\r
+}\r
+\r
+#ifdef __VISUALC__\r
+ #pragma warning(default:4611)\r
+#endif /* VC++ */\r
+\r
+// recognize the 0xFF4F JPEG 2000 SOC marker\r
+bool wxJ2KHandler::DoCanRead( wxInputStream& stream )\r
+{\r
+ unsigned char hdr[2];\r
+\r
+ if ( !stream.Read(hdr, WXSIZEOF(hdr)) )\r
+ return false;\r
+\r
+ return hdr[0] == 0xFF && hdr[1] == 0x4F;\r
+}\r
+\r
+#endif // wxUSE_STREAMS\r
+\r
+#endif // wxUSE_LIBOPENJPEG\r
--- /dev/null
+/*\r
+ * Copyright (c) 2007, Digital Signal Processing Laboratory, Università degli studi di Perugia (UPG), Italy\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * 1. Redistributions of source code must retain the above copyright\r
+ * notice, this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ * notice, this list of conditions and the following disclaimer in the\r
+ * documentation and/or other materials provided with the distribution.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'\r
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\r
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
+ * POSSIBILITY OF SUCH DAMAGE.\r
+ */\r
+/////////////////////////////////////////////////////////////////////////////\r
+// Name: imagj2k.h\r
+// Purpose: wxImage JPEG 2000 raw codestream handler\r
+// Author: G. Baruffa - based on imagjpeg.h, Vaclav Slavik\r
+// RCS-ID: $Id: imagj2k.h,v 0.0 2007/02/08 23:45:00 VZ Exp $\r
+// Copyright: (c) Giuseppe Baruffa\r
+// Licence: wxWindows licence\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+#ifndef _WX_IMAGJ2K_H_\r
+#define _WX_IMAGJ2K_H_\r
+\r
+#include "wx/defs.h"\r
+\r
+//-----------------------------------------------------------------------------\r
+// wxJ2KHandler\r
+//-----------------------------------------------------------------------------\r
+\r
+#if wxUSE_LIBOPENJPEG\r
+\r
+#include "wx/image.h"\r
+\r
+#define wxBITMAP_TYPE_J2K 47\r
+\r
+class WXDLLEXPORT wxJ2KHandler: public wxImageHandler\r
+{\r
+public:\r
+ inline wxJ2KHandler()\r
+ {\r
+ m_name = wxT("JPEG 2000 codestream file");\r
+ m_extension = wxT("j2k");\r
+ m_type = wxBITMAP_TYPE_J2K;\r
+ m_mime = wxT("image/j2k");\r
+ }\r
+\r
+#if wxUSE_STREAMS\r
+ virtual bool LoadFile( wxImage *image, wxInputStream& stream, bool verbose=true, int index=-1 );\r
+ virtual bool SaveFile( wxImage *image, wxOutputStream& stream, bool verbose=true );\r
+protected:\r
+ virtual bool DoCanRead( wxInputStream& stream );\r
+#endif\r
+\r
+private:\r
+ DECLARE_DYNAMIC_CLASS(wxJ2KHandler)\r
+};\r
+\r
+#endif // wxUSE_LIBOPENJPEG\r
+\r
+#endif // _WX_IMAGJ2K_H_\r
+\r
--- /dev/null
+/*\r
+ * Copyright (c) 2007, Digital Signal Processing Laboratory, Università degli studi di Perugia (UPG), Italy\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * 1. Redistributions of source code must retain the above copyright\r
+ * notice, this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ * notice, this list of conditions and the following disclaimer in the\r
+ * documentation and/or other materials provided with the distribution.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'\r
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\r
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
+ * POSSIBILITY OF SUCH DAMAGE.\r
+ */\r
+/////////////////////////////////////////////////////////////////////////////\r
+// Name: imagjp2.cpp\r
+// Purpose: wxImage JPEG 2000 file format handler\r
+// Author: Giuseppe Baruffa - based on imagjpeg.cpp, Vaclav Slavik\r
+// RCS-ID: $Id: imagjp2.cpp,v 0.00 2007/02/08 23:59:00 MW Exp $\r
+// Copyright: (c) Giuseppe Baruffa\r
+// Licence: wxWindows licence\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+// For compilers that support precompilation, includes "wx.h".\r
+#include "wx/wxprec.h"\r
+\r
+#ifdef __BORLANDC__\r
+ #pragma hdrstop\r
+#endif\r
+\r
+#if wxUSE_IMAGE && wxUSE_LIBOPENJPEG\r
+\r
+#include "imagjp2.h"\r
+\r
+#ifndef WX_PRECOMP\r
+ #include "wx/log.h"\r
+ #include "wx/app.h"\r
+ #include "wx/intl.h"\r
+ #include "wx/bitmap.h"\r
+ #include "wx/module.h"\r
+#endif\r
+\r
+\r
+#include "libopenjpeg/openjpeg.h"\r
+\r
+\r
+#include "wx/filefn.h"\r
+#include "wx/wfstream.h"\r
+\r
+// ----------------------------------------------------------------------------\r
+// types\r
+// ----------------------------------------------------------------------------\r
+\r
+\r
+//-----------------------------------------------------------------------------\r
+// wxJP2Handler\r
+//-----------------------------------------------------------------------------\r
+\r
+IMPLEMENT_DYNAMIC_CLASS(wxJP2Handler,wxImageHandler)\r
+\r
+#if wxUSE_STREAMS\r
+\r
+//------------- JPEG 2000 Data Source Manager\r
+\r
+#define J2K_CFMT 0\r
+#define JP2_CFMT 1\r
+#define JPT_CFMT 2\r
+#define MJ2_CFMT 3\r
+#define PXM_DFMT 0\r
+#define PGX_DFMT 1\r
+#define BMP_DFMT 2\r
+#define YUV_DFMT 3\r
+\r
+#define MAX_MESSAGE_LEN 200\r
+\r
+/* sample error callback expecting a FILE* client object */\r
+void jp2_error_callback(const char *msg, void *client_data) {\r
+ char m_msg[MAX_MESSAGE_LEN];\r
+ int message_len = strlen(msg) - 1;\r
+ if (msg[message_len] != '\n')\r
+ message_len = MAX_MESSAGE_LEN;\r
+ sprintf(m_msg, "[ERROR] %.*s", message_len, msg);\r
+ wxMutexGuiEnter();\r
+ wxLogMessage(m_msg);\r
+ wxMutexGuiLeave();\r
+}\r
+/* sample warning callback expecting a FILE* client object */\r
+void jp2_warning_callback(const char *msg, void *client_data) {\r
+ char m_msg[MAX_MESSAGE_LEN];\r
+ int message_len = strlen(msg) - 1;\r
+ if (msg[message_len] != '\n')\r
+ message_len = MAX_MESSAGE_LEN;\r
+ sprintf(m_msg, "[WARNING] %.*s", message_len, msg);\r
+ wxMutexGuiEnter();\r
+ wxLogMessage(m_msg);\r
+ wxMutexGuiLeave();\r
+}\r
+/* sample debug callback expecting no client object */\r
+void jp2_info_callback(const char *msg, void *client_data) {\r
+ char m_msg[MAX_MESSAGE_LEN];\r
+ int message_len = strlen(msg) - 1;\r
+ if (msg[message_len] != '\n')\r
+ message_len = MAX_MESSAGE_LEN;\r
+ sprintf(m_msg, "[INFO] %.*s", message_len, msg);\r
+ wxMutexGuiEnter();\r
+ wxLogMessage(m_msg);\r
+ wxMutexGuiLeave();\r
+}\r
+\r
+// load the jp2 file format\r
+bool wxJP2Handler::LoadFile(wxImage *image, wxInputStream& stream, bool verbose, int index)\r
+{\r
+ opj_dparameters_t parameters; /* decompression parameters */\r
+ opj_event_mgr_t event_mgr; /* event manager */\r
+ opj_image_t *opjimage = NULL;\r
+ FILE *fsrc = NULL;\r
+ unsigned char *src = NULL;\r
+ unsigned char *ptr;\r
+ int file_length;\r
+\r
+ // destroy the image\r
+ image->Destroy();\r
+\r
+ /* handle to a decompressor */\r
+ opj_dinfo_t* dinfo = NULL; \r
+ opj_cio_t *cio = NULL;\r
+\r
+ /* configure the event callbacks (not required) */\r
+ memset(&event_mgr, 0, sizeof(opj_event_mgr_t));\r
+ event_mgr.error_handler = jp2_error_callback;\r
+ event_mgr.warning_handler = jp2_warning_callback;\r
+ event_mgr.info_handler = jp2_info_callback;\r
+\r
+ /* set decoding parameters to default values */\r
+ opj_set_default_decoder_parameters(¶meters);\r
+\r
+ /* prepare parameters */\r
+ parameters.decod_format = JP2_CFMT;\r
+ parameters.cod_format = BMP_DFMT;\r
+\r
+ /* get a decoder handle */\r
+ dinfo = opj_create_decompress(CODEC_JP2);\r
+\r
+ /* find length of the stream */\r
+ stream.SeekI(0, wxFromEnd);\r
+ file_length = (int) stream.TellI();\r
+\r
+ /* get data */\r
+ stream.SeekI(0, wxFromStart);\r
+ src = (unsigned char *) malloc(file_length);\r
+ stream.Read(src, file_length);\r
+\r
+ /* catch events using our callbacks and give a local context */\r
+ opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, stderr);\r
+\r
+ /* setup the decoder decoding parameters using user parameters */\r
+ opj_setup_decoder(dinfo, ¶meters);\r
+\r
+ /* open a byte stream */\r
+ cio = opj_cio_open((opj_common_ptr)dinfo, src, file_length);\r
+\r
+ /* decode the stream and fill the image structure */\r
+ opjimage = opj_decode(dinfo, cio);\r
+ if (!opjimage) {\r
+ wxMutexGuiEnter();\r
+ wxLogError("JP2: failed to decode image!");\r
+ wxMutexGuiLeave();\r
+ opj_destroy_decompress(dinfo);\r
+ opj_cio_close(cio);\r
+ free(src);\r
+ return false;\r
+ }\r
+\r
+ // check image size\r
+ if ((opjimage->numcomps != 1) && (opjimage->numcomps != 3)) {\r
+ wxMutexGuiEnter();\r
+ wxLogError("JP2: weird number of components");\r
+ wxMutexGuiLeave();\r
+ opj_destroy_decompress(dinfo);\r
+ opj_cio_close(cio);\r
+ free(src);\r
+ return false;\r
+ }\r
+\r
+ // prepare image size\r
+ image->Create(opjimage->comps[0].w, opjimage->comps[0].h, true );\r
+\r
+ // access image raw data\r
+ image->SetMask( false );\r
+ ptr = image->GetData();\r
+\r
+ // RGB color picture\r
+ if (opjimage->numcomps == 3) {\r
+ int row, col;\r
+ int *r = opjimage->comps[0].data;\r
+ int *g = opjimage->comps[1].data;\r
+ int *b = opjimage->comps[2].data;\r
+ for (row = 0; row < opjimage->comps[0].h; row++) {\r
+ for (col = 0; col < opjimage->comps[0].w; col++) {\r
+ \r
+ *(ptr++) = *(r++);\r
+ *(ptr++) = *(g++);\r
+ *(ptr++) = *(b++);\r
+\r
+ }\r
+ }\r
+ }\r
+\r
+ // B/W picture\r
+ if (opjimage->numcomps == 1) {\r
+ int row, col;\r
+ int *y = opjimage->comps[0].data;\r
+ for (row = 0; row < opjimage->comps[0].h; row++) {\r
+ for (col = 0; col < opjimage->comps[0].w; col++) {\r
+ \r
+ *(ptr++) = *(y);\r
+ *(ptr++) = *(y);\r
+ *(ptr++) = *(y++);\r
+\r
+ }\r
+ }\r
+ }\r
+\r
+ wxMutexGuiEnter();\r
+ wxLogMessage(wxT("JP2: image loaded."));\r
+ wxMutexGuiLeave();\r
+\r
+ /* close openjpeg structs */\r
+ opj_destroy_decompress(dinfo);\r
+ opj_cio_close(cio);\r
+ opj_image_destroy(opjimage);\r
+ free(src);\r
+\r
+ if (!image->Ok())\r
+ return false;\r
+ else\r
+ return true;\r
+\r
+}\r
+\r
+// save the jp2 file format\r
+bool wxJP2Handler::SaveFile( wxImage *image, wxOutputStream& stream, bool verbose )\r
+{\r
+ wxLogError(wxT("JP2: Couldn't save image -> not implemented."));\r
+ return false;\r
+}\r
+\r
+#ifdef __VISUALC__\r
+ #pragma warning(default:4611)\r
+#endif /* VC++ */\r
+\r
+// recognize the JPEG 2000 starting box\r
+bool wxJP2Handler::DoCanRead( wxInputStream& stream )\r
+{\r
+ unsigned char hdr[23];\r
+\r
+ if ( !stream.Read(hdr, WXSIZEOF(hdr)) )\r
+ return false;\r
+\r
+ return (hdr[0] == 0x00 &&\r
+ hdr[1] == 0x00 &&\r
+ hdr[2] == 0x00 &&\r
+ hdr[3] == 0x0C &&\r
+ hdr[4] == 0x6A &&\r
+ hdr[5] == 0x50 &&\r
+ hdr[6] == 0x20 &&\r
+ hdr[7] == 0x20 &&\r
+ hdr[20] == 0x6A &&\r
+ hdr[21] == 0x70 &&\r
+ hdr[22] == 0x32);\r
+}\r
+\r
+#endif // wxUSE_STREAMS\r
+\r
+#endif // wxUSE_LIBOPENJPEG\r
--- /dev/null
+/*\r
+ * Copyright (c) 2007, Digital Signal Processing Laboratory, Università degli studi di Perugia (UPG), Italy\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * 1. Redistributions of source code must retain the above copyright\r
+ * notice, this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ * notice, this list of conditions and the following disclaimer in the\r
+ * documentation and/or other materials provided with the distribution.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'\r
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\r
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
+ * POSSIBILITY OF SUCH DAMAGE.\r
+ */\r
+/////////////////////////////////////////////////////////////////////////////\r
+// Name: imagjp2.h\r
+// Purpose: wxImage JPEG 2000 file format handler\r
+// Author: G. Baruffa - based on imagjpeg.h, Vaclav Slavik\r
+// RCS-ID: $Id: imagjp2.h,v 0.0 2007/02/08 23:45:00 VZ Exp $\r
+// Copyright: (c) Giuseppe Baruffa\r
+// Licence: wxWindows licence\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+#ifndef _WX_IMAGJP2_H_\r
+#define _WX_IMAGJP2_H_\r
+\r
+#include "wx/defs.h"\r
+\r
+//-----------------------------------------------------------------------------\r
+// wxJP2Handler\r
+//-----------------------------------------------------------------------------\r
+\r
+#if wxUSE_LIBOPENJPEG\r
+\r
+#include "wx/image.h"\r
+\r
+#define wxBITMAP_TYPE_JP2 48\r
+\r
+class WXDLLEXPORT wxJP2Handler: public wxImageHandler\r
+{\r
+public:\r
+ inline wxJP2Handler()\r
+ {\r
+ m_name = wxT("JPEG 2000 file format");\r
+ m_extension = wxT("jp2");\r
+ m_type = wxBITMAP_TYPE_JP2;\r
+ m_mime = wxT("image/jp2");\r
+ }\r
+\r
+#if wxUSE_STREAMS\r
+ virtual bool LoadFile( wxImage *image, wxInputStream& stream, bool verbose=true, int index=-1 );\r
+ virtual bool SaveFile( wxImage *image, wxOutputStream& stream, bool verbose=true );\r
+protected:\r
+ virtual bool DoCanRead( wxInputStream& stream );\r
+#endif\r
+\r
+private:\r
+ DECLARE_DYNAMIC_CLASS(wxJP2Handler)\r
+};\r
+\r
+#endif // wxUSE_LIBOPENJPEG\r
+\r
+#endif // _WX_IMAGJP2_H_\r
+\r
--- /dev/null
+/*\r
+ * Copyright (c) 2007, Digital Signal Processing Laboratory, Università degli studi di Perugia (UPG), Italy\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * 1. Redistributions of source code must retain the above copyright\r
+ * notice, this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ * notice, this list of conditions and the following disclaimer in the\r
+ * documentation and/or other materials provided with the distribution.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'\r
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\r
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
+ * POSSIBILITY OF SUCH DAMAGE.\r
+ */\r
+/////////////////////////////////////////////////////////////////////////////\r
+// Name: imagmj2.cpp\r
+// Purpose: wxImage Motion JPEG 2000 file format handler\r
+// Author: Giuseppe Baruffa - based on imagjpeg.cpp, Vaclav Slavik\r
+// RCS-ID: $Id: imagmj2.cpp,v 0.00 2007/02/18 23:59:00 MW Exp $\r
+// Copyright: (c) Giuseppe Baruffa\r
+// Licence: wxWindows licence\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+// For compilers that support precompilation, includes "wx.h".\r
+#include "wx/wxprec.h"\r
+\r
+#ifdef __BORLANDC__\r
+ #pragma hdrstop\r
+#endif\r
+\r
+#if wxUSE_IMAGE && wxUSE_LIBOPENJPEG\r
+\r
+#include "imagmj2.h"\r
+\r
+#ifndef WX_PRECOMP\r
+ #include "wx/log.h"\r
+ #include "wx/app.h"\r
+ #include "wx/intl.h"\r
+ #include "wx/bitmap.h"\r
+ #include "wx/module.h"\r
+#endif\r
+\r
+\r
+#include "libopenjpeg/openjpeg.h"\r
+\r
+\r
+#include "wx/filefn.h"\r
+#include "wx/wfstream.h"\r
+\r
+// ----------------------------------------------------------------------------\r
+// types\r
+// ----------------------------------------------------------------------------\r
+\r
+\r
+//-----------------------------------------------------------------------------\r
+// wxMJ2Handler\r
+//-----------------------------------------------------------------------------\r
+\r
+IMPLEMENT_DYNAMIC_CLASS(wxMJ2Handler,wxImageHandler)\r
+\r
+#if wxUSE_STREAMS\r
+\r
+//------------- JPEG 2000 Data Source Manager\r
+\r
+#define J2K_CFMT 0\r
+#define JP2_CFMT 1\r
+#define JPT_CFMT 2\r
+#define MJ2_CFMT 3\r
+#define PXM_DFMT 0\r
+#define PGX_DFMT 1\r
+#define BMP_DFMT 2\r
+#define YUV_DFMT 3\r
+\r
+#define MAX_MESSAGE_LEN 200\r
+\r
+/* sample error callback expecting a FILE* client object */\r
+void mj2_error_callback(const char *msg, void *client_data) {\r
+ char m_msg[MAX_MESSAGE_LEN];\r
+ int message_len = strlen(msg) - 1;\r
+ if (msg[message_len] != '\n')\r
+ message_len = MAX_MESSAGE_LEN;\r
+ sprintf(m_msg, "[ERROR] %.*s", message_len, msg);\r
+ wxMutexGuiEnter();\r
+ wxLogMessage(m_msg);\r
+ wxMutexGuiLeave();\r
+}\r
+/* sample warning callback expecting a FILE* client object */\r
+void mj2_warning_callback(const char *msg, void *client_data) {\r
+ char m_msg[MAX_MESSAGE_LEN];\r
+ int message_len = strlen(msg) - 1;\r
+ if (msg[message_len] != '\n')\r
+ message_len = MAX_MESSAGE_LEN;\r
+ sprintf(m_msg, "[WARNING] %.*s", message_len, msg);\r
+ wxMutexGuiEnter();\r
+ wxLogMessage(m_msg);\r
+ wxMutexGuiLeave();\r
+}\r
+/* sample debug callback expecting no client object */\r
+void mj2_info_callback(const char *msg, void *client_data) {\r
+ char m_msg[MAX_MESSAGE_LEN];\r
+ int message_len = strlen(msg) - 1;\r
+ if (msg[message_len] != '\n')\r
+ message_len = MAX_MESSAGE_LEN;\r
+ sprintf(m_msg, "[INFO] %.*s", message_len, msg);\r
+ wxMutexGuiEnter();\r
+ wxLogMessage(m_msg);\r
+ wxMutexGuiLeave();\r
+}\r
+\r
+/* macro functions */\r
+/* From little endian to big endian, 2 and 4 bytes */\r
+#define BYTE_SWAP2(X) ((X & 0x00FF) << 8) | ((X & 0xFF00) >> 8)\r
+#define BYTE_SWAP4(X) ((X & 0x000000FF) << 24) | ((X & 0x0000FF00) << 8) | ((X & 0x00FF0000) >> 8) | ((X & 0xFF000000) >> 24)\r
+#define BYTE_SWAP8(X) ((X & 0x00000000000000FF) << 56) | ((X & 0x000000000000FF00) << 40) | \\r
+ ((X & 0x0000000000FF0000) << 24) | ((X & 0x00000000FF000000) << 8) | \\r
+ ((X & 0x000000FF00000000) >> 8) | ((X & 0x0000FF0000000000) >> 24) | \\r
+ ((X & 0x00FF000000000000) >> 40) | ((X & 0xFF00000000000000) >> 56)\r
+\r
+/* From codestream to int values */\r
+#define STREAM_TO_UINT32(C, P) (((unsigned long int) (C)[(P) + 0] << 24) + \\r
+ ((unsigned long int) (C)[(P) + 1] << 16) + \\r
+ ((unsigned long int) (C)[(P) + 2] << 8) + \\r
+ ((unsigned long int) (C)[(P) + 3] << 0))\r
+\r
+#define STREAM_TO_UINT16(C, P) (((unsigned long int) (C)[(P) + 0] << 8) + \\r
+ ((unsigned long int) (C)[(P) + 1] << 0))\r
+\r
+/* defines */\r
+#define SHORT_DESCR_LEN 32\r
+#define LONG_DESCR_LEN 256\r
+\r
+/* enumeration for file formats */\r
+#define J2FILENUM 4\r
+typedef enum {\r
+\r
+ JP2_FILE,\r
+ J2K_FILE,\r
+ MJ2_FILE,\r
+ UNK_FILE\r
+\r
+} my_j2filetype;\r
+\r
+/* enumeration for the box types */\r
+#define J2BOXNUM 23\r
+typedef enum {\r
+\r
+ FILE_BOX,\r
+ JP_BOX,\r
+ FTYP_BOX,\r
+ JP2H_BOX,\r
+ IHDR_BOX,\r
+ COLR_BOX,\r
+ JP2C_BOX,\r
+ JP2I_BOX,\r
+ XML_BOX,\r
+ UUID_BOX,\r
+ UINF_BOX,\r
+ MOOV_BOX,\r
+ MVHD_BOX,\r
+ TRAK_BOX,\r
+ TKHD_BOX,\r
+ MDIA_BOX,\r
+ MINF_BOX,\r
+ STBL_BOX,\r
+ STSD_BOX,\r
+ MJP2_BOX,\r
+ MDAT_BOX,\r
+ ANY_BOX,\r
+ UNK_BOX\r
+\r
+} my_j2boxtype;\r
+\r
+/* jp2 family box signatures */\r
+#define FILE_SIGN ""\r
+#define JP_SIGN "jP\040\040"\r
+#define FTYP_SIGN "ftyp"\r
+#define JP2H_SIGN "jp2h"\r
+#define IHDR_SIGN "ihdr"\r
+#define COLR_SIGN "colr"\r
+#define JP2C_SIGN "jp2c"\r
+#define JP2I_SIGN "jp2i"\r
+#define XML_SIGN "xml\040"\r
+#define UUID_SIGN "uuid"\r
+#define UINF_SIGN "uinf"\r
+#define MOOV_SIGN "moov"\r
+#define MVHD_SIGN "mvhd"\r
+#define TRAK_SIGN "trak"\r
+#define TKHD_SIGN "tkhd"\r
+#define MDIA_SIGN "mdia"\r
+#define MINF_SIGN "minf"\r
+#define STBL_SIGN "stbl"\r
+#define STSD_SIGN "stsd"\r
+#define MJP2_SIGN "mjp2"\r
+#define MDAT_SIGN "mdat"\r
+#define ANY_SIGN ""\r
+#define UNK_SIGN ""\r
+\r
+/* the box structure itself */\r
+struct my_boxdef {\r
+\r
+ char value[5]; /* hexadecimal value/string*/\r
+ char name[SHORT_DESCR_LEN]; /* short description */\r
+ char descr[LONG_DESCR_LEN]; /* long description */\r
+ int sbox; /* is it a superbox? */\r
+ int req[J2FILENUM]; /* mandatory box */\r
+ my_j2boxtype ins; /* contained in box... */\r
+\r
+};\r
+\r
+/* the possible boxes */\r
+struct my_boxdef j2box[] =\r
+{\r
+/* sign */ {FILE_SIGN,\r
+/* short */ "placeholder for nothing",\r
+/* long */ "Nothing to say",\r
+/* sbox */ 0,\r
+/* req */ {1, 1, 1},\r
+/* ins */ FILE_BOX},\r
+\r
+/* sign */ {JP_SIGN,\r
+/* short */ "JPEG 2000 Signature box",\r
+/* long */ "This box uniquely identifies the file as being part of the JPEG 2000 family of files",\r
+/* sbox */ 0,\r
+/* req */ {1, 1, 1},\r
+/* ins */ FILE_BOX},\r
+\r
+/* sign */ {FTYP_SIGN,\r
+/* short */ "File Type box",\r
+/* long */ "This box specifies file type, version and compatibility information, including specifying if this file "\r
+ "is a conforming JP2 file or if it can be read by a conforming JP2 reader",\r
+/* sbox */ 0,\r
+/* req */ {1, 1, 1},\r
+/* ins */ FILE_BOX},\r
+\r
+/* sign */ {JP2H_SIGN,\r
+/* short */ "JP2 Header box",\r
+/* long */ "This box contains a series of boxes that contain header-type information about the file",\r
+/* sbox */ 1,\r
+/* req */ {1, 1, 1},\r
+/* ins */ FILE_BOX},\r
+\r
+/* sign */ {IHDR_SIGN,\r
+/* short */ "Image Header box",\r
+/* long */ "This box specifies the size of the image and other related fields",\r
+/* sbox */ 0,\r
+/* req */ {1, 1, 1},\r
+/* ins */ JP2H_BOX},\r
+\r
+/* sign */ {COLR_SIGN,\r
+/* short */ "Colour Specification box",\r
+/* long */ "This box specifies the colourspace of the image",\r
+/* sbox */ 0,\r
+/* req */ {1, 1, 1},\r
+/* ins */ JP2H_BOX},\r
+\r
+/* sign */ {JP2C_SIGN,\r
+/* short */ "Contiguous Codestream box",\r
+/* long */ "This box contains the codestream as defined by Annex A",\r
+/* sbox */ 0,\r
+/* req */ {1, 1, 1},\r
+/* ins */ FILE_BOX},\r
+\r
+/* sign */ {JP2I_SIGN,\r
+/* short */ "Intellectual Property box",\r
+/* long */ "This box contains intellectual property information about the image",\r
+/* sbox */ 0,\r
+/* req */ {0, 0, 0},\r
+/* ins */ FILE_BOX},\r
+\r
+/* sign */ {XML_SIGN,\r
+/* short */ "XML box",\r
+/* long */ "This box provides a tool by which vendors can add XML formatted information to a JP2 file",\r
+/* sbox */ 0,\r
+/* req */ {0, 0, 0},\r
+/* ins */ FILE_BOX},\r
+\r
+/* sign */ {UUID_SIGN,\r
+/* short */ "UUID box",\r
+/* long */ "This box provides a tool by which vendors can add additional information to a file "\r
+ "without risking conflict with other vendors",\r
+/* sbox */ 0,\r
+/* req */ {0, 0, 0},\r
+/* ins */ FILE_BOX},\r
+\r
+/* sign */ {UINF_SIGN,\r
+/* short */ "UUID Info box",\r
+/* long */ "This box provides a tool by which a vendor may provide access to additional information associated with a UUID",\r
+/* sbox */ 0,\r
+/* req */ {0, 0, 0},\r
+/* ins */ FILE_BOX},\r
+\r
+/* sign */ {MOOV_SIGN,\r
+/* short */ "Movie box",\r
+/* long */ "This box contains the media data. In video tracks, this box would contain JPEG2000 video frames",\r
+/* sbox */ 1,\r
+/* req */ {1, 1, 1},\r
+/* ins */ FILE_BOX},\r
+\r
+/* sign */ {MVHD_SIGN,\r
+/* short */ "Movie Header box",\r
+/* long */ "This box defines overall information which is media-independent, and relevant to the entire presentation "\r
+ "considered as a whole",\r
+/* sbox */ 0,\r
+/* req */ {1, 1, 1},\r
+/* ins */ MOOV_BOX},\r
+\r
+/* sign */ {TRAK_SIGN,\r
+/* short */ "Track box",\r
+/* long */ "This is a container box for a single track of a presentation. A presentation may consist of one or more tracks",\r
+/* sbox */ 1,\r
+/* req */ {1, 1, 1},\r
+/* ins */ MOOV_BOX},\r
+\r
+/* sign */ {TKHD_SIGN,\r
+/* short */ "Track Header box",\r
+/* long */ "This box specifies the characteristics of a single track. Exactly one Track Header Box is contained in a track",\r
+/* sbox */ 0,\r
+/* req */ {1, 1, 1},\r
+/* ins */ TRAK_BOX},\r
+\r
+/* sign */ {MDIA_SIGN,\r
+/* short */ "Media box",\r
+/* long */ "The media declaration container contains all the objects which declare information about the media data "\r
+ "within a track",\r
+/* sbox */ 1,\r
+/* req */ {1, 1, 1},\r
+/* ins */ TRAK_BOX},\r
+\r
+/* sign */ {MINF_SIGN,\r
+/* short */ "Media Information box",\r
+/* long */ "This box contains all the objects which declare characteristic information of the media in the track",\r
+/* sbox */ 1,\r
+/* req */ {1, 1, 1},\r
+/* ins */ MDIA_BOX},\r
+\r
+/* sign */ {STBL_SIGN,\r
+/* short */ "Sample Table box",\r
+/* long */ "The sample table contains all the time and data indexing of the media samples in a track",\r
+/* sbox */ 1,\r
+/* req */ {1, 1, 1},\r
+/* ins */ MINF_BOX},\r
+\r
+/* sign */ {STSD_SIGN,\r
+/* short */ "Sample Description box",\r
+/* long */ "The sample description table gives detailed information about the coding type used, and any initialization "\r
+ "information needed for that coding",\r
+/* sbox */ 0,\r
+/* req */ {1, 1, 1},\r
+/* ins */ MINF_BOX},\r
+\r
+/* sign */ {MJP2_SIGN,\r
+/* short */ "MJP2 Sample Description box",\r
+/* long */ "The MJP2 sample description table gives detailed information about the coding type used, and any initialization "\r
+ "information needed for that coding",\r
+/* sbox */ 0,\r
+/* req */ {1, 1, 1},\r
+/* ins */ MINF_BOX},\r
+\r
+/* sign */ {MDAT_SIGN,\r
+/* short */ "Media Data box",\r
+/* long */ "The meta-data for a presentation is stored in the single Movie Box which occurs at the top-level of a file",\r
+/* sbox */ 1,\r
+/* req */ {1, 1, 1},\r
+/* ins */ FILE_BOX},\r
+\r
+/* sign */ {ANY_SIGN,\r
+/* short */ "Any box",\r
+/* long */ "All the existing boxes",\r
+/* sbox */ 0,\r
+/* req */ {0, 0, 0},\r
+/* ins */ FILE_BOX},\r
+\r
+/* sign */ {UNK_SIGN,\r
+/* short */ "Unknown Type box",\r
+/* long */ "The signature is not recognised to be that of an existing box",\r
+/* sbox */ 0,\r
+/* req */ {0, 0, 0},\r
+/* ins */ ANY_BOX}\r
+\r
+};\r
+\r
+/* declaration */\r
+int\r
+my_box_handler_function(my_j2boxtype boxtype, wxInputStream& stream, unsigned long int filepoint, unsigned long int filelimit, int level,\r
+ char *scansign, unsigned long int *scanpoint);\r
+\r
+/* internal mini-search for a box signature */\r
+int\r
+my_jpeg2000parse(wxInputStream& stream, unsigned long int filepoint, unsigned long int filelimit, int level,\r
+ char *scansign, unsigned long int *scanpoint)\r
+{\r
+ unsigned long int LBox = 0x00000000;\r
+ int LBox_read;\r
+ char TBox[5] = "\0\0\0\0";\r
+ int TBox_read;\r
+ __int64 XLBox = 0x0000000000000000;\r
+ int XLBox_read;\r
+ unsigned long int box_length = 0;\r
+ int last_box = 0, box_num = 0;\r
+ int box_type = ANY_BOX;\r
+ unsigned char onebyte[1], twobytes[2], fourbytes[4];\r
+ int box_number = 0;\r
+\r
+ /* cycle all over the file */\r
+ box_num = 0;\r
+ last_box = 0;\r
+ while (!last_box) {\r
+\r
+ /* do not exceed file limit */\r
+ if (filepoint >= filelimit)\r
+ return (0);\r
+\r
+ /* seek on file */\r
+ if (stream.SeekI(filepoint, wxFromStart) == wxInvalidOffset)\r
+ return (-1);\r
+\r
+ /* read the mandatory LBox, 4 bytes */\r
+ if (!stream.Read(fourbytes, 4)) {\r
+ (wxT("Problem reading LBox from the file (file ended?)"));\r
+ return -1;\r
+ };\r
+ LBox = STREAM_TO_UINT32(fourbytes, 0);\r
+\r
+ /* read the mandatory TBox, 4 bytes */\r
+ if (!stream.Read(TBox, 4)) {\r
+ wxLogError(wxT("Problem reading TBox from the file (file ended?)"));\r
+ return -1;\r
+ };\r
+\r
+ /* look if scansign is got */\r
+ if ((scansign != NULL) && (memcmp(TBox, scansign, 4) == 0)) {\r
+ /* hack/exploit */\r
+ // stop as soon as you find the level-th codebox\r
+ if (box_number == level) {\r
+ memcpy(scansign, " ", 4);\r
+ *scanpoint = filepoint;\r
+ return (0);\r
+ } else\r
+ box_number++;\r
+\r
+ };\r
+\r
+\r
+ /* determine the box type */\r
+ for (box_type = JP_BOX; box_type < UNK_BOX; box_type++)\r
+ if (memcmp(TBox, j2box[box_type].value, 4) == 0)\r
+ break; \r
+\r
+ /* read the optional XLBox, 8 bytes */\r
+ if (LBox == 1) {\r
+\r
+ if (!stream.Read(&XLBox, 8)) {\r
+ wxLogError(wxT("Problem reading XLBox from the file (file ended?)"));\r
+ return -1;\r
+ };\r
+ box_length = (unsigned long int) BYTE_SWAP8(XLBox);\r
+\r
+ } else if (LBox == 0x00000000) {\r
+\r
+ /* last box in file */\r
+ last_box = 1; \r
+ box_length = filelimit - filepoint;\r
+\r
+ } else\r
+\r
+ box_length = LBox;\r
+\r
+\r
+ /* go deep in the box */\r
+ my_box_handler_function((my_j2boxtype) box_type, stream, (LBox == 1) ? (filepoint + 16) : (filepoint + 8), filepoint + box_length, level,\r
+ scansign, scanpoint);\r
+\r
+ /* if it's a superbox go inside it */\r
+ if (j2box[box_type].sbox)\r
+ my_jpeg2000parse(stream, (LBox == 1) ? (filepoint + 16) : (filepoint + 8), filepoint + box_length,\r
+ level, scansign, scanpoint);\r
+\r
+ /* increment box number and filepoint*/\r
+ box_num++;\r
+ filepoint += box_length;\r
+\r
+ };\r
+\r
+ /* all good */\r
+ return (0);\r
+}\r
+\r
+// search first contiguos codestream box in an mj2 file\r
+unsigned long int\r
+searchfirstjp2c(wxInputStream& stream, unsigned long int fsize)\r
+{\r
+ char scansign[] = "jp2c";\r
+ unsigned long int scanpoint = 0L;\r
+\r
+ wxLogMessage("MJ2: searching jp2c box... ");\r
+\r
+ /* do the parsing */\r
+ if (my_jpeg2000parse(stream, 0, fsize, 0, scansign, &scanpoint) < 0) \r
+ wxLogMessage("MJ2: Unrecoverable error during file parsing: stopping");\r
+\r
+ if (strcmp(scansign, " "))\r
+ wxLogMessage("MJ2: not found");\r
+ else {\r
+\r
+ wxLogMessage(wxString::Format("MJ2: found at byte %d", scanpoint));\r
+\r
+ };\r
+\r
+\r
+ return (scanpoint);\r
+}\r
+\r
+// search the jp2h box in the file\r
+unsigned long int\r
+searchjpegheaderbox(wxInputStream& stream, unsigned long int fsize)\r
+{\r
+ char scansign[] = "jp2h";\r
+ unsigned long int scanpoint = 0L;\r
+\r
+ wxLogMessage("MJ2: searching jp2h box... ");\r
+\r
+ /* do the parsing */\r
+ if (my_jpeg2000parse(stream, 0, fsize, 0, scansign, &scanpoint) < 0) \r
+ wxLogMessage("Unrecoverable error during file parsing: stopping");\r
+\r
+ if (strcmp(scansign, " "))\r
+ wxLogMessage("MJ2: not found");\r
+ else\r
+ wxLogMessage(wxString::Format("MJ2: found at byte %d", scanpoint));\r
+\r
+ return (scanpoint);\r
+}\r
+\r
+/* handling functions */\r
+#define ITEM_PER_ROW 10\r
+\r
+/* Box handler function */\r
+int\r
+my_box_handler_function(my_j2boxtype boxtype, wxInputStream& stream, unsigned long int filepoint, unsigned long int filelimit, int level,\r
+ char *scansign, unsigned long int *scanpoint)\r
+{\r
+ switch (boxtype) {\r
+\r
+ /* Sample Description box */\r
+ case (STSD_BOX):\r
+ my_jpeg2000parse(stream, filepoint + 8, filelimit, level, scansign, scanpoint);\r
+ break;\r
+\r
+ /* MJP2 Sample Description box */\r
+ case (MJP2_BOX):\r
+ my_jpeg2000parse(stream, filepoint + 78, filelimit, level, scansign, scanpoint);\r
+ break;\r
+ \r
+ /* not yet implemented */\r
+ default:\r
+ break;\r
+\r
+ };\r
+\r
+ return (0);\r
+}\r
+\r
+// the jP and ftyp parts of the header\r
+#define my_jPheadSIZE 32\r
+unsigned char my_jPhead[my_jPheadSIZE] = {\r
+ 0x00, 0x00, 0x00, 0x0C, 'j', 'P', ' ', ' ',\r
+ 0x0D, 0x0A, 0x87, 0x0A, 0x00, 0x00, 0x00, 0x14,\r
+ 'f', 't', 'y', 'p', 'j', 'p', '2', ' ',\r
+ 0x00, 0x00, 0x00, 0x00, 'j', 'p', '2', ' ' \r
+};\r
+\r
+/////////////////////////////////////////////////\r
+/////////////////////////////////////////////////\r
+\r
+// load the mj2 file format\r
+bool wxMJ2Handler::LoadFile(wxImage *image, wxInputStream& stream, bool verbose, int index)\r
+{\r
+ opj_dparameters_t parameters; /* decompression parameters */\r
+ opj_event_mgr_t event_mgr; /* event manager */\r
+ opj_image_t *opjimage = NULL;\r
+ FILE *fsrc = NULL;\r
+ unsigned char *src = NULL;\r
+ unsigned char *ptr;\r
+ int file_length, jp2c_point, jp2h_point;\r
+ unsigned long int jp2hboxlen, jp2cboxlen;\r
+\r
+ // destroy the image\r
+ image->Destroy();\r
+\r
+ /* handle to a decompressor */\r
+ opj_dinfo_t* dinfo = NULL; \r
+ opj_cio_t *cio = NULL;\r
+\r
+ /* configure the event callbacks (not required) */\r
+ memset(&event_mgr, 0, sizeof(opj_event_mgr_t));\r
+ event_mgr.error_handler = mj2_error_callback;\r
+ event_mgr.warning_handler = mj2_warning_callback;\r
+ event_mgr.info_handler = mj2_info_callback;\r
+\r
+ /* set decoding parameters to default values */\r
+ opj_set_default_decoder_parameters(¶meters);\r
+\r
+ /* prepare parameters */\r
+ parameters.decod_format = JP2_CFMT;\r
+ parameters.cod_format = BMP_DFMT;\r
+\r
+ /* get a decoder handle */\r
+ dinfo = opj_create_decompress(CODEC_JP2);\r
+\r
+ /* find length of the stream */\r
+ stream.SeekI(0, wxFromEnd);\r
+ file_length = (int) stream.TellI();\r
+\r
+ /* search for the first codestream box and the movie header box */\r
+ jp2c_point = searchfirstjp2c(stream, file_length);\r
+ jp2h_point = searchjpegheaderbox(stream, file_length);\r
+\r
+ // read the jp2h box and store it\r
+ stream.SeekI(jp2h_point, wxFromStart);\r
+ stream.Read(&jp2hboxlen, sizeof(unsigned long int));\r
+ jp2hboxlen = BYTE_SWAP4(jp2hboxlen);\r
+\r
+ // read the jp2c box and store it\r
+ stream.SeekI(jp2c_point, wxFromStart);\r
+ stream.Read(&jp2cboxlen, sizeof(unsigned long int));\r
+ jp2cboxlen = BYTE_SWAP4(jp2cboxlen);\r
+\r
+ // malloc memory source\r
+ src = (unsigned char *) malloc(my_jPheadSIZE + jp2hboxlen + jp2cboxlen);\r
+\r
+ // copy the jP and ftyp\r
+ memcpy(src, my_jPhead, my_jPheadSIZE);\r
+\r
+ // copy the jp2h\r
+ stream.SeekI(jp2h_point, wxFromStart);\r
+ stream.Read(&src[my_jPheadSIZE], jp2hboxlen);\r
+\r
+ // copy the jp2c\r
+ stream.SeekI(jp2c_point, wxFromStart);\r
+ stream.Read(&src[my_jPheadSIZE + jp2hboxlen], jp2cboxlen);\r
+\r
+ /* catch events using our callbacks and give a local context */\r
+ opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, stderr);\r
+\r
+ /* setup the decoder decoding parameters using user parameters */\r
+ opj_setup_decoder(dinfo, ¶meters);\r
+\r
+ /* open a byte stream */\r
+ cio = opj_cio_open((opj_common_ptr)dinfo, src, my_jPheadSIZE + jp2hboxlen + jp2cboxlen);\r
+\r
+ /* decode the stream and fill the image structure */\r
+ opjimage = opj_decode(dinfo, cio);\r
+ if (!opjimage) {\r
+ wxMutexGuiEnter();\r
+ wxLogError("MJ2: failed to decode image!");\r
+ wxMutexGuiLeave();\r
+ opj_destroy_decompress(dinfo);\r
+ opj_cio_close(cio);\r
+ free(src);\r
+ return false;\r
+ }\r
+\r
+ // check image size\r
+ if ((opjimage->numcomps != 1) && (opjimage->numcomps != 3)) {\r
+ wxMutexGuiEnter();\r
+ wxLogError("MJ2: weird number of components");\r
+ wxMutexGuiLeave();\r
+ opj_destroy_decompress(dinfo);\r
+ opj_cio_close(cio);\r
+ free(src);\r
+ return false;\r
+ }\r
+\r
+ // prepare image size\r
+ image->Create(opjimage->comps[0].w, opjimage->comps[0].h, true );\r
+\r
+ // access image raw data\r
+ image->SetMask( false );\r
+ ptr = image->GetData();\r
+\r
+ // RGB color picture\r
+ // does not handle comps. subsampling,\r
+ // so simply render the first component\r
+ if (opjimage->numcomps == 3) {\r
+ int row, col;\r
+ int *r = opjimage->comps[0].data;\r
+ /*\r
+ int *g = opjimage->comps[1].data;\r
+ int *b = opjimage->comps[2].data;\r
+ */\r
+ for (row = 0; row < opjimage->comps[0].h; row++) {\r
+ for (col = 0; col < opjimage->comps[0].w; col++) {\r
+ \r
+ /*\r
+ *(ptr++) = *(r++);\r
+ *(ptr++) = *(g++);\r
+ *(ptr++) = *(b++);\r
+ */\r
+ *(ptr++) = *(r);\r
+ *(ptr++) = *(r);\r
+ *(ptr++) = *(r++);\r
+\r
+ }\r
+ }\r
+ }\r
+\r
+ // B/W picture\r
+ if (opjimage->numcomps == 1) {\r
+ int row, col;\r
+ int *y = opjimage->comps[0].data;\r
+ for (row = 0; row < opjimage->comps[0].h; row++) {\r
+ for (col = 0; col < opjimage->comps[0].w; col++) {\r
+ \r
+ *(ptr++) = *(y);\r
+ *(ptr++) = *(y);\r
+ *(ptr++) = *(y++);\r
+\r
+ }\r
+ }\r
+ }\r
+\r
+ wxMutexGuiEnter();\r
+ wxLogMessage(wxT("MJ2: image loaded."));\r
+ wxMutexGuiLeave();\r
+\r
+ /* close openjpeg structs */\r
+ opj_destroy_decompress(dinfo);\r
+ opj_cio_close(cio);\r
+ opj_image_destroy(opjimage);\r
+ free(src);\r
+\r
+ if (!image->Ok())\r
+ return false;\r
+ else\r
+ return true;\r
+\r
+}\r
+\r
+// save the mj2 file format\r
+bool wxMJ2Handler::SaveFile( wxImage *image, wxOutputStream& stream, bool verbose )\r
+{\r
+ wxLogError(wxT("MJ2: Couldn't save movie -> not implemented."));\r
+ return false;\r
+}\r
+\r
+#ifdef __VISUALC__\r
+ #pragma warning(default:4611)\r
+#endif /* VC++ */\r
+\r
+// recognize the Motion JPEG 2000 starting box\r
+bool wxMJ2Handler::DoCanRead( wxInputStream& stream )\r
+{\r
+ unsigned char hdr[24];\r
+\r
+ if ( !stream.Read(hdr, WXSIZEOF(hdr)) )\r
+ return false;\r
+\r
+ return (hdr[0] == 0x00 &&\r
+ hdr[1] == 0x00 &&\r
+ hdr[2] == 0x00 &&\r
+ hdr[3] == 0x0C &&\r
+ hdr[4] == 0x6A &&\r
+ hdr[5] == 0x50 &&\r
+ hdr[6] == 0x20 &&\r
+ hdr[7] == 0x20 &&\r
+ hdr[20] == 0x6D &&\r
+ hdr[21] == 0x6A &&\r
+ hdr[22] == 0x70 &&\r
+ hdr[23] == 0x32);\r
+}\r
+\r
+#endif // wxUSE_STREAMS\r
+\r
+#endif // wxUSE_LIBOPENJPEG\r
--- /dev/null
+/*\r
+ * Copyright (c) 2007, Digital Signal Processing Laboratory, Università degli studi di Perugia (UPG), Italy\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * 1. Redistributions of source code must retain the above copyright\r
+ * notice, this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ * notice, this list of conditions and the following disclaimer in the\r
+ * documentation and/or other materials provided with the distribution.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'\r
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\r
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
+ * POSSIBILITY OF SUCH DAMAGE.\r
+ */\r
+/////////////////////////////////////////////////////////////////////////////\r
+// Name: imagmj2.h\r
+// Purpose: wxImage Motion JPEG 2000 file format handler\r
+// Author: G. Baruffa - based on imagjpeg.h, Vaclav Slavik\r
+// RCS-ID: $Id: imagmj2.h,v 0.0 2007/02/18 23:45:00 VZ Exp $\r
+// Copyright: (c) Giuseppe Baruffa\r
+// Licence: wxWindows licence\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+#ifndef _WX_IMAGMJ2_H_\r
+#define _WX_IMAGMJ2_H_\r
+\r
+#include "wx/defs.h"\r
+\r
+//-----------------------------------------------------------------------------\r
+// wxMJ2Handler\r
+//-----------------------------------------------------------------------------\r
+\r
+#if wxUSE_LIBOPENJPEG\r
+\r
+#include "wx/image.h"\r
+\r
+#define wxBITMAP_TYPE_MJ2 49\r
+\r
+class WXDLLEXPORT wxMJ2Handler: public wxImageHandler\r
+{\r
+public:\r
+ inline wxMJ2Handler()\r
+ {\r
+ m_name = wxT("Motion JPEG 2000 file format");\r
+ m_extension = wxT("mj2");\r
+ m_type = wxBITMAP_TYPE_MJ2;\r
+ m_mime = wxT("image/mj2");\r
+ }\r
+\r
+#if wxUSE_STREAMS\r
+ virtual bool LoadFile( wxImage *image, wxInputStream& stream, bool verbose=true, int index=-1 );\r
+ virtual bool SaveFile( wxImage *image, wxOutputStream& stream, bool verbose=true );\r
+protected:\r
+ virtual bool DoCanRead( wxInputStream& stream );\r
+#endif\r
+\r
+private:\r
+ DECLARE_DYNAMIC_CLASS(wxMJ2Handler)\r
+};\r
+\r
+#endif // wxUSE_LIBOPENJPEG\r
+\r
+#endif // _WX_IMAGMJ2_H_\r
+\r
--- /dev/null
+/*\r
+ * Copyright (c) 2007, Digital Signal Processing Laboratory, Università degli studi di Perugia (UPG), Italy\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * 1. Redistributions of source code must retain the above copyright\r
+ * notice, this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ * notice, this list of conditions and the following disclaimer in the\r
+ * documentation and/or other materials provided with the distribution.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'\r
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\r
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
+ * POSSIBILITY OF SUCH DAMAGE.\r
+ */\r
+#include "OPJViewer.h"\r
+\r
+/* From little endian to big endian, 2 bytes */\r
+#define BYTE_SWAP2(X) ((X & 0x00FF) << 8) | ((X & 0xFF00) >> 8)\r
+#define BYTE_SWAP4(X) ((X & 0x000000FF) << 24) | ((X & 0x0000FF00) << 8) | ((X & 0x00FF0000) >> 8) | ((X & 0xFF000000) >> 24)\r
+\r
+/* From codestream to int values */\r
+#define STREAM_TO_UINT32(C, P) (((unsigned long int) (C)[(P) + 0] << 24) + \\r
+ ((unsigned long int) (C)[(P) + 1] << 16) + \\r
+ ((unsigned long int) (C)[(P) + 2] << 8) + \\r
+ ((unsigned long int) (C)[(P) + 3] << 0))\r
+\r
+#define STREAM_TO_UINT16(C, P) (((unsigned long int) (C)[(P) + 0] << 8) + \\r
+ ((unsigned long int) (C)[(P) + 1] << 0))\r
+\r
+\r
+/* Markers values */\r
+enum {\r
+ SOC_VAL = 0xFF4F,\r
+ SOT_VAL = 0xFF90,\r
+ SOD_VAL = 0xFF93,\r
+ EOC_VAL = 0xFFD9,\r
+ SIZ_VAL = 0xFF51,\r
+ COD_VAL = 0xFF52,\r
+ COC_VAL = 0xFF53,\r
+ RGN_VAL = 0xFF5E,\r
+ QCD_VAL = 0xFF5C,\r
+ QCC_VAL = 0xFF5D,\r
+ POD_VAL = 0xFF5F,\r
+ TLM_VAL = 0xFF55,\r
+ PLM_VAL = 0xFF57,\r
+ PLT_VAL = 0xFF58,\r
+ PPM_VAL = 0xFF60,\r
+ PPT_VAL = 0xFF61,\r
+ SOP_VAL = 0xFF91,\r
+ EPH_VAL = 0xFF92,\r
+ CME_VAL = 0xFF64,\r
+#ifndef USEOLDJPWL \r
+ EPB_VAL = 0xFF66,\r
+ ESD_VAL = 0xFF67,\r
+ EPC_VAL = 0xFF68,\r
+ RED_VAL = 0xFF69\r
+#else\r
+ EPB_VAL = 0xFF96,\r
+ ESD_VAL = 0xFF98,\r
+ EPC_VAL = 0xFF97,\r
+ RED_VAL = 0xFF99\r
+#endif\r
+};\r
+\r
+// All the markers in one vector\r
+unsigned short int marker_val[] = {\r
+ SOC_VAL, SOT_VAL, SOD_VAL, EOC_VAL,\r
+ SIZ_VAL,\r
+ COD_VAL, COC_VAL, RGN_VAL, QCD_VAL, QCC_VAL, POD_VAL,\r
+ TLM_VAL, PLM_VAL, PLT_VAL, PPM_VAL, PPT_VAL,\r
+ SOP_VAL, EPH_VAL,\r
+ CME_VAL,\r
+ EPB_VAL, ESD_VAL, EPC_VAL, RED_VAL\r
+};\r
+\r
+// Marker names\r
+char *marker_name[] = {\r
+ "SOC", "SOT", "SOD", "EOC",\r
+ "SIZ",\r
+ "COD", "COC", "RGN", "QCD", "QCC", "POD",\r
+ "TLM", "PLM", "PLT", "PPM", "PPT",\r
+ "SOP", "EPH",\r
+ "CME",\r
+ "EPB", "ESD", "EPC", "RED"\r
+};\r
+\r
+// Marker descriptions\r
+char *marker_descr[] = {\r
+ "Start of codestream", "Start of tile-part", "Start of data", "End of codestream",\r
+ "Image and tile size",\r
+ "Coding style default", "Coding style component", "Region-of-interest", "Quantization default",\r
+ "Quantization component", "Progression order change, default",\r
+ "Tile-part lengths, main header", "Packet length, main header", "Packets length, tile-part header",\r
+ "Packed packet headers, main header", "Packed packet headers, tile-part header",\r
+ "Start of packet", "End of packet header",\r
+ "Comment and extension",\r
+ "Error Protection Block", "Error Sensitivity Descriptor", "Error Protection Capability",\r
+ "Residual Errors Descriptor"\r
+};\r
+\r
+void OPJParseThread::ParseJ2KFile(wxFile *m_file, wxFileOffset offset, wxFileOffset length, wxTreeItemId parentid)\r
+{\r
+ // check if the file is opened\r
+ if (m_file->IsOpened())\r
+ WriteText(wxT("File OK"));\r
+ else\r
+ return;\r
+\r
+ // position at the beginning\r
+ m_file->Seek(offset, wxFromStart);\r
+\r
+ //WriteText(wxString::Format(wxT("from to %d"), length));\r
+\r
+ // navigate the file\r
+ int m, inside_sod = 0, nmarks = 0, maxmarks = 10000, done = 0;\r
+ unsigned char onebyte[1];\r
+ unsigned char twobytes[2];\r
+ unsigned char fourbytes[4];\r
+ unsigned short int currmark;\r
+ unsigned short int currlen;\r
+ int lastPsot = 0, lastsotpos = 0;\r
+\r
+ WriteText(wxT("Start search..."));\r
+ while ((offset < length) && (!m_file->Eof())) {\r
+\r
+ done = 0;\r
+\r
+ // read da marka\r
+ if (m_file->Read(twobytes, 2) != 2)\r
+ break;\r
+ currmark = (((unsigned short int) twobytes[0]) << 8) + (unsigned short int) twobytes[1];\r
+\r
+ // Markers cycle\r
+ for (m = 0; m < 23; m++) {\r
+\r
+ // check the marker\r
+ if (currmark == marker_val[m]) {\r
+\r
+ if (currmark == SOD_VAL) {\r
+\r
+ // we enter SOD\r
+ currlen = 0;\r
+ inside_sod = 1;\r
+\r
+ } else if ((currmark == SOC_VAL) || (currmark == EOC_VAL) || (currmark == EPH_VAL))\r
+ \r
+ currlen = 0;\r
+\r
+ else {\r
+\r
+ // read length\r
+ if (m_file->Read(twobytes, 2) != 2)\r
+ break;\r
+ currlen = (((unsigned short int) twobytes[0]) << 8) + (unsigned short int) twobytes[1];\r
+\r
+ }\r
+\r
+ // inside SOD, only some markers are allowed\r
+ if (inside_sod && (currmark != SOD_VAL) && (currmark != SOT_VAL)\r
+ && (currmark != EOC_VAL) && (currmark != SOP_VAL) && (currmark != EPH_VAL))\r
+ break; /*randomly marker coincident data */\r
+\r
+ if (inside_sod && (currmark == SOT_VAL) && (lastPsot == 0))\r
+ inside_sod = 0; /* random data coincident with SOT, but last SOT was the last one */\r
+\r
+ if (inside_sod && (currmark == SOT_VAL))\r
+ inside_sod = 0; /* new tile part */\r
+\r
+ // here we pass to AppendItem() normal and selected item images (we\r
+ // suppose that selected image follows the normal one in the enum)\r
+ int image, imageSel;\r
+ image = m_tree->TreeCtrlIcon_Folder;\r
+ imageSel = image + 1;\r
+\r
+ // append the marker\r
+ wxTreeItemId currid = m_tree->AppendItem(parentid,\r
+ wxString::Format(wxT("%03d: %s (0x%04X)"), nmarks, marker_name[m], marker_val[m]),\r
+ image, imageSel,\r
+ new OPJMarkerData(wxT("MARK"), m_tree->m_fname.GetFullPath(), offset, offset + currlen + 1)\r
+ );\r
+\r
+ // append some info\r
+ image = m_tree->TreeCtrlIcon_File;\r
+ imageSel = image + 1;\r
+\r
+ // marker name\r
+ wxTreeItemId subcurrid1 = m_tree->AppendItem(currid,\r
+ wxT("*** ") + wxString(marker_descr[m]) + wxT(" ***"),\r
+ image, imageSel,\r
+ new OPJMarkerData(wxT("INFO"))\r
+ );\r
+ m_tree->SetItemFont(subcurrid1, *wxITALIC_FONT);\r
+\r
+ // position and length\r
+ wxTreeItemId subcurrid2 = m_tree->AppendItem(currid,\r
+ wxLongLong(offset).ToString() + wxT(" > ") + wxLongLong(offset + currlen + 1).ToString() + \r
+ wxT(", ") + wxString::Format(wxT("%d + 2 (%d)"), currlen, currlen + 2),\r
+ image, imageSel,\r
+ new OPJMarkerData(wxT("INFO"))\r
+ );\r
+\r
+ // give additional info on markers\r
+ switch (currmark) {\r
+ \r
+ case SOP_VAL:\r
+ {\r
+ // read packet number\r
+ if (m_file->Read(twobytes, 2) != 2)\r
+ break;\r
+ int packnum = STREAM_TO_UINT16(twobytes, 0);;\r
+ wxTreeItemId subcurrid3 = m_tree->AppendItem(currid,\r
+ wxString::Format(wxT("Pack. no. %d"), packnum),\r
+ image, imageSel,\r
+ new OPJMarkerData(wxT("INFO"))\r
+ );\r
+ }\r
+ break;\r
+\r
+ case SIZ_VAL:\r
+ {\r
+ m_file->Seek(2, wxFromCurrent);\r
+ if (m_file->Read(fourbytes, 4) != 4)\r
+ break;\r
+ unsigned long int xsiz = STREAM_TO_UINT32(fourbytes, 0);\r
+\r
+ if (m_file->Read(fourbytes, 4) != 4)\r
+ break;\r
+ unsigned long int ysiz = STREAM_TO_UINT32(fourbytes, 0);\r
+\r
+ m_file->Seek(24, wxFromCurrent);\r
+ if (m_file->Read(twobytes, 2) != 2)\r
+ break;\r
+ unsigned short int csiz = STREAM_TO_UINT16(twobytes, 0);\r
+\r
+ if (m_file->Read(onebyte, 1) != 1)\r
+ break;\r
+ unsigned char ssiz = onebyte[0];\r
+\r
+ wxTreeItemId subcurrid3 = m_tree->AppendItem(currid,\r
+ wxString::Format(wxT("%d x %d, %d comps. @ %d bpp"), xsiz, ysiz, csiz, (ssiz + 1) & 0xEF),\r
+ image, imageSel,\r
+ new OPJMarkerData(wxT("INFO"))\r
+ );\r
+\r
+ }\r
+ break;\r
+\r
+ case SOT_VAL:\r
+ {\r
+ if (m_file->Read(twobytes, 2) != 2)\r
+ break;\r
+ unsigned short int isot = STREAM_TO_UINT16(twobytes, 0);\r
+\r
+ if (m_file->Read(fourbytes, 4) != 4)\r
+ break;\r
+ unsigned long int psot = STREAM_TO_UINT32(fourbytes, 0);\r
+\r
+ if (m_file->Read(onebyte, 1) != 1)\r
+ break;\r
+ unsigned char tpsot = onebyte[0];\r
+\r
+ if (m_file->Read(onebyte, 1) != 1)\r
+ break;\r
+ unsigned char tnsot = onebyte[0];\r
+\r
+ wxTreeItemId subcurrid3 = m_tree->AppendItem(currid,\r
+ wxString::Format(wxT("tile %d, psot = %d, part %d of %d"), isot, psot, tpsot, tnsot),\r
+ image, imageSel,\r
+ new OPJMarkerData(wxT("INFO"))\r
+ );\r
+\r
+ lastPsot = psot;\r
+ lastsotpos = offset;\r
+ };\r
+ break;\r
+\r
+ case CME_VAL:\r
+ {\r
+ #define showlen 25\r
+ unsigned char comment[showlen];\r
+\r
+ m_file->Seek(2, wxFromCurrent);\r
+ if (m_file->Read(comment, showlen) != showlen)\r
+ break;\r
+\r
+ wxTreeItemId subcurrid3 = m_tree->AppendItem(currid,\r
+ wxString::Format(wxT("%.*s%s"), wxMin(showlen, currlen - 4), comment,\r
+ (((currlen - 4) > showlen) ? "..." : "")),\r
+ image, imageSel,\r
+ new OPJMarkerData(wxT("INFO"))\r
+ );\r
+ }\r
+ break;\r
+\r
+ default:\r
+ break;\r
+ }\r
+ \r
+ \r
+ // increment number of markers\r
+ nmarks++;\r
+ if (nmarks >= maxmarks)\r
+ break;\r
+\r
+ // increment offset\r
+ if (currmark == SOD_VAL)\r
+ offset += lastPsot - (offset - lastsotpos);\r
+ else\r
+ offset += (2 + currlen);\r
+\r
+ m_file->Seek(offset, wxFromStart);\r
+ done = 1;\r
+\r
+ break;\r
+ }\r
+ }\r
+\r
+ if (done)\r
+ continue;\r
+ else {\r
+ offset++;\r
+ m_file->Seek(offset, wxFromStart);\r
+ }\r
+ }\r
+ \r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2007, Digital Signal Processing Laboratory, Università degli studi di Perugia (UPG), Italy\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * 1. Redistributions of source code must retain the above copyright\r
+ * notice, this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ * notice, this list of conditions and the following disclaimer in the\r
+ * documentation and/or other materials provided with the distribution.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'\r
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\r
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
+ * POSSIBILITY OF SUCH DAMAGE.\r
+ */\r
+#include "OPJViewer.h"\r
+\r
+/* defines */\r
+#define SHORT_DESCR_LEN 32\r
+#define LONG_DESCR_LEN 256\r
+\r
+/* enumeration for file formats */\r
+#define J2FILENUM 4\r
+typedef enum {\r
+\r
+ JP2_FILE,\r
+ J2K_FILE,\r
+ MJ2_FILE,\r
+ UNK_FILE\r
+\r
+} j2filetype;\r
+\r
+/* enumeration for the box types */\r
+#define J2BOXNUM 23\r
+typedef enum {\r
+\r
+ FILE_BOX,\r
+ JP_BOX,\r
+ FTYP_BOX,\r
+ JP2H_BOX,\r
+ IHDR_BOX,\r
+ COLR_BOX,\r
+ JP2C_BOX,\r
+ JP2I_BOX,\r
+ XML_BOX,\r
+ UUID_BOX,\r
+ UINF_BOX,\r
+ MOOV_BOX,\r
+ MVHD_BOX,\r
+ TRAK_BOX,\r
+ TKHD_BOX,\r
+ MDIA_BOX,\r
+ MINF_BOX,\r
+ STBL_BOX,\r
+ STSD_BOX,\r
+ MJP2_BOX,\r
+ MDAT_BOX,\r
+ ANY_BOX,\r
+ UNK_BOX\r
+\r
+} j2boxtype;\r
+\r
+/* the box structure itself */\r
+struct boxdef {\r
+\r
+ char value[5]; /* hexadecimal value/string*/\r
+ char name[SHORT_DESCR_LEN]; /* short description */\r
+ char descr[LONG_DESCR_LEN]; /* long description */\r
+ int sbox; /* is it a superbox? */\r
+ int req[J2FILENUM]; /* mandatory box */\r
+ j2boxtype ins; /* contained in box... */\r
+\r
+};\r
+\r
+/* the possible boxes */\r
+struct boxdef j2box[];\r
+\r
+/* macro functions */\r
+/* From little endian to big endian, 2 and 4 bytes */\r
+#define BYTE_SWAP2(X) ((X & 0x00FF) << 8) | ((X & 0xFF00) >> 8)\r
+#define BYTE_SWAP4(X) ((X & 0x000000FF) << 24) | ((X & 0x0000FF00) << 8) | ((X & 0x00FF0000) >> 8) | ((X & 0xFF000000) >> 24)\r
+#define BYTE_SWAP8(X) (((X & 0x00000000000000FF) << 56) | ((X & 0x000000000000FF00) << 40) | \\r
+ ((X & 0x0000000000FF0000) << 24) | ((X & 0x00000000FF000000) << 8) | \\r
+ ((X & 0x000000FF00000000) >> 8) | ((X & 0x0000FF0000000000) >> 24) | \\r
+ ((X & 0x00FF000000000000) >> 40) | ((X & 0xFF00000000000000) >> 56))\r
+\r
+/* From codestream to int values */\r
+#define STREAM_TO_UINT32(C, P) (((unsigned long int) (C)[(P) + 0] << 24) + \\r
+ ((unsigned long int) (C)[(P) + 1] << 16) + \\r
+ ((unsigned long int) (C)[(P) + 2] << 8) + \\r
+ ((unsigned long int) (C)[(P) + 3] << 0))\r
+\r
+#define STREAM_TO_UINT16(C, P) (((unsigned long int) (C)[(P) + 0] << 8) + \\r
+ ((unsigned long int) (C)[(P) + 1] << 0))\r
+\r
+#define OPJREAD_LONG(F,L,N) { \\r
+ if (F->Read(fourbytes, 4) < 4) { \\r
+ wxLogMessage(wxT("Problem reading " N " from the file (file ended?)")); \\r
+ return -1; \\r
+ }; \\r
+ L = STREAM_TO_UINT32(fourbytes, 0); \\r
+ }\r
+\r
+/* handling functions */\r
+#define ITEM_PER_ROW 10\r
+\r
+//#define indprint if (0) printf("%.*s", 2 * level + 9, indent), printf\r
+char indent[] = " "\r
+ " "\r
+ " "\r
+ " ";\r
+\r
+void indprint(wxString printout, int level)\r
+{\r
+ wxLogMessage(/*wxString::Format(wxT("%.*s"), 2 * level + 9, indent) + */printout);\r
+}\r
+\r
+/* Box handler function */\r
+int OPJParseThread::box_handler_function(int boxtype, wxFile *fileid, wxFileOffset filepoint, wxFileOffset filelimit,\r
+ wxTreeItemId parentid, int level, char *scansign, unsigned long int *scanpoint)\r
+{\r
+ switch ((j2boxtype) boxtype) {\r
+\r
+\r
+ /* JPEG 2000 Signature box */\r
+ case (JP_BOX): {\r
+\r
+ unsigned long int checkdata = 0;\r
+ fileid->Read(&checkdata, sizeof(unsigned long int));\r
+ checkdata = BYTE_SWAP4(checkdata);\r
+\r
+ // add info\r
+ wxTreeItemId currid = m_tree->AppendItem(parentid,\r
+ wxString::Format(wxT("Check data: %X -> %s"), checkdata, (checkdata == 0x0D0A870A) ? wxT("OK") : wxT("KO")),\r
+ m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,\r
+ new OPJMarkerData(wxT("INFO"))\r
+ );\r
+\r
+ };\r
+ break;\r
+\r
+\r
+ /* JPEG 2000 codestream box */\r
+ case (JP2C_BOX): {\r
+\r
+ // add info\r
+ wxTreeItemId currid = m_tree->AppendItem(parentid,\r
+ wxString(wxT("Codestream")),\r
+ m_tree->TreeCtrlIcon_Folder, m_tree->TreeCtrlIcon_Folder + 1,\r
+ new OPJMarkerData(wxT("INFO-CSTREAM"), m_tree->m_fname.GetFullPath(), filepoint, filelimit)\r
+ );\r
+\r
+ m_tree->SetItemHasChildren(currid);\r
+\r
+ // parse the file\r
+ //ParseJ2KFile(fileid, filepoint, filelimit, currid);\r
+\r
+ };\r
+ break;\r
+\r
+\r
+\r
+\r
+\r
+ /* File Type box */\r
+ case (FTYP_BOX): {\r
+\r
+ char BR[4], CL[4];\r
+ unsigned long int MinV, numCL, i;\r
+ fileid->Read(BR, sizeof(char) * 4);\r
+ fileid->Read(&MinV, sizeof(unsigned long int));\r
+ MinV = BYTE_SWAP4(MinV);\r
+ numCL = (filelimit - fileid->Tell()) / 4; \r
+\r
+ // add info\r
+ wxTreeItemId currid = m_tree->AppendItem(parentid,\r
+ wxString::Format(wxT("Brand/Minor version: %.4s/%d"), BR, MinV),\r
+ m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,\r
+ new OPJMarkerData(wxT("INFO"))\r
+ );\r
+\r
+ currid = m_tree->AppendItem(parentid,\r
+ wxString::Format(wxT("Compatibility list")),\r
+ m_tree->TreeCtrlIcon_Folder, m_tree->TreeCtrlIcon_Folder + 1,\r
+ new OPJMarkerData(wxT("INFO"))\r
+ );\r
+\r
+ for (i = 0; i < numCL; i++) {\r
+ fileid->Read(CL, sizeof(char) * 4);\r
+ m_tree->AppendItem(currid,\r
+ wxString::Format(wxT("%.4s"), CL),\r
+ m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,\r
+ new OPJMarkerData(wxT("INFO"))\r
+ );\r
+ };\r
+ \r
+ };\r
+ break;\r
+\r
+\r
+\r
+ /* JP2 Header box */\r
+ case (IHDR_BOX): {\r
+\r
+ unsigned long int height, width;\r
+ unsigned short int nc;\r
+ unsigned char bpc, C, UnkC, IPR;\r
+ fileid->Read(&height, sizeof(unsigned long int));\r
+ height = BYTE_SWAP4(height);\r
+ fileid->Read(&width, sizeof(unsigned long int));\r
+ width = BYTE_SWAP4(width);\r
+ fileid->Read(&nc, sizeof(unsigned short int));\r
+ nc = BYTE_SWAP2(nc);\r
+ fileid->Read(&bpc, sizeof(unsigned char));\r
+ fileid->Read(&C, sizeof(unsigned char));\r
+ fileid->Read(&UnkC, sizeof(unsigned char));\r
+ fileid->Read(&IPR, sizeof(unsigned char));\r
+ \r
+ // add info\r
+ wxTreeItemId currid = m_tree->AppendItem(parentid,\r
+ wxString::Format(wxT("Dimensions: %d x %d x %d @ %d bpc"), width, height, nc, bpc + 1),\r
+ m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,\r
+ new OPJMarkerData(wxT("INFO"))\r
+ );\r
+\r
+ currid = m_tree->AppendItem(parentid,\r
+ wxString::Format(wxT("Compression type: %d"), C),\r
+ m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,\r
+ new OPJMarkerData(wxT("INFO"))\r
+ );\r
+\r
+ currid = m_tree->AppendItem(parentid,\r
+ wxString::Format(wxT("Colourspace unknown: %d"), UnkC),\r
+ m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,\r
+ new OPJMarkerData(wxT("INFO"))\r
+ );\r
+\r
+ currid = m_tree->AppendItem(parentid,\r
+ wxString::Format(wxT("Intellectual Property Rights: %d"), IPR),\r
+ m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,\r
+ new OPJMarkerData(wxT("INFO"))\r
+ );\r
+ \r
+ };\r
+ break;\r
+\r
+\r
+\r
+ /* Colour Specification box */\r
+ case (COLR_BOX): {\r
+\r
+ unsigned char METH, PREC, APPROX;\r
+ char methdescr[80], enumcsdescr[80];\r
+ unsigned long int EnumCS;\r
+ fileid->Read(&METH, sizeof(unsigned char));\r
+ switch (METH) {\r
+ case 1:\r
+ strcpy(methdescr, "Enumerated Colourspace");\r
+ break;\r
+ case 2:\r
+ strcpy(methdescr, "Restricted ICC profile");\r
+ break;\r
+ default:\r
+ strcpy(methdescr, "Unknown");\r
+ break;\r
+ };\r
+ fileid->Read(&PREC, sizeof(unsigned char));\r
+ fileid->Read(&APPROX, sizeof(unsigned char));\r
+ if (METH != 2) {\r
+ fileid->Read(&EnumCS, sizeof(unsigned long int));\r
+ EnumCS = BYTE_SWAP4(EnumCS);\r
+ switch (EnumCS) {\r
+ case 16:\r
+ strcpy(enumcsdescr, "sRGB");\r
+ break;\r
+ case 17:\r
+ strcpy(enumcsdescr, "greyscale");\r
+ break;\r
+ case 18:\r
+ strcpy(enumcsdescr, "sYCC");\r
+ break;\r
+ default:\r
+ strcpy(enumcsdescr, "Unknown");\r
+ break;\r
+ };\r
+ };\r
+\r
+ // add info\r
+ wxTreeItemId currid = m_tree->AppendItem(parentid,\r
+ wxString::Format(wxT("Specification method: %d (%s)"), METH, methdescr),\r
+ m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,\r
+ new OPJMarkerData(wxT("INFO"))\r
+ );\r
+\r
+ currid = m_tree->AppendItem(parentid,\r
+ wxString::Format(wxT("Precedence: %d"), PREC),\r
+ m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,\r
+ new OPJMarkerData(wxT("INFO"))\r
+ );\r
+\r
+ currid = m_tree->AppendItem(parentid,\r
+ wxString::Format(wxT("Colourspace approximation: %d"), APPROX),\r
+ m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,\r
+ new OPJMarkerData(wxT("INFO"))\r
+ );\r
+\r
+ if (METH != 2)\r
+ currid = m_tree->AppendItem(parentid,\r
+ wxString::Format(wxT("Enumerated colourspace: %d (%s)"), EnumCS, enumcsdescr),\r
+ m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,\r
+ new OPJMarkerData(wxT("INFO"))\r
+ );\r
+\r
+ if (METH != 1)\r
+ currid = m_tree->AppendItem(parentid,\r
+ wxString::Format("ICC profile: there is one"),\r
+ m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,\r
+ new OPJMarkerData(wxT("INFO"))\r
+ );\r
+\r
+\r
+ };\r
+ break;\r
+\r
+\r
+\r
+\r
+ \r
+\r
+ /* Movie Header Box */\r
+ case (MVHD_BOX): {\r
+\r
+ unsigned long int version, rate, matrix[9], next_track_ID;\r
+ unsigned short int volume;\r
+ fileid->Read(&version, sizeof(unsigned long int));\r
+ version = BYTE_SWAP4(version);\r
+ if (version == 0) {\r
+ unsigned long int creation_time, modification_time, timescale, duration;\r
+ fileid->Read(&creation_time, sizeof(unsigned long int));\r
+ creation_time = BYTE_SWAP4(creation_time);\r
+ fileid->Read(&modification_time, sizeof(unsigned long int));\r
+ modification_time = BYTE_SWAP4(modification_time);\r
+ fileid->Read(×cale, sizeof(unsigned long int));\r
+ timescale = BYTE_SWAP4(timescale);\r
+ fileid->Read(&duration, sizeof(unsigned long int));\r
+ duration = BYTE_SWAP4(duration);\r
+ const long unix_time = creation_time - 2082844800L;\r
+ wxTreeItemId currid = m_tree->AppendItem(parentid,\r
+ wxString::Format(wxT("Creation time: %u (%.24s)"), creation_time, ctime(&unix_time)),\r
+ m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,\r
+ new OPJMarkerData(wxT("INFO"))\r
+ );\r
+ const long unix_time1 = modification_time - 2082844800L;\r
+ currid = m_tree->AppendItem(parentid,\r
+ wxString::Format(wxT("Modification time: %u (%.24s)"), modification_time, ctime(&unix_time1)),\r
+ m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,\r
+ new OPJMarkerData(wxT("INFO"))\r
+ );\r
+ currid = m_tree->AppendItem(parentid,\r
+ wxString::Format(wxT("Timescale: %u (%.6fs)"), timescale, 1.0 / (float) timescale),\r
+ m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,\r
+ new OPJMarkerData(wxT("INFO"))\r
+ );\r
+ currid = m_tree->AppendItem(parentid,\r
+ wxString::Format(wxT("Duration: %u (%.3fs)"), duration, (float) duration / (float) timescale),\r
+ m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,\r
+ new OPJMarkerData(wxT("INFO"))\r
+ );\r
+ } else {\r
+ unsigned __int64 creation_time, modification_time, duration;\r
+ unsigned long int timescale;\r
+ fileid->Read(&creation_time, sizeof(unsigned __int64));\r
+ creation_time = BYTE_SWAP8(creation_time);\r
+ fileid->Read(&modification_time, sizeof(unsigned __int64));\r
+ modification_time = BYTE_SWAP8(modification_time);\r
+ fileid->Read(×cale, sizeof(unsigned long int));\r
+ timescale = BYTE_SWAP4(timescale);\r
+ fileid->Read(&duration, sizeof(unsigned __int64));\r
+ duration = BYTE_SWAP8(duration);\r
+ wxTreeItemId currid = m_tree->AppendItem(parentid,\r
+ wxString::Format(wxT("Creation time: %u"), creation_time),\r
+ m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,\r
+ new OPJMarkerData(wxT("INFO"))\r
+ );\r
+ currid = m_tree->AppendItem(parentid,\r
+ wxString::Format(wxT("Modification time: %u"), modification_time),\r
+ m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,\r
+ new OPJMarkerData(wxT("INFO"))\r
+ );\r
+ currid = m_tree->AppendItem(parentid,\r
+ wxString::Format(wxT("Timescale: %u"), timescale),\r
+ m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,\r
+ new OPJMarkerData(wxT("INFO"))\r
+ );\r
+ currid = m_tree->AppendItem(parentid,\r
+ wxString::Format(wxT("Duration: %u"), duration),\r
+ m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,\r
+ new OPJMarkerData(wxT("INFO"))\r
+ );\r
+ };\r
+ fileid->Read(&rate, sizeof(unsigned long int));\r
+ rate = BYTE_SWAP4(rate);\r
+ fileid->Read(&volume, sizeof(unsigned short int));\r
+ volume = BYTE_SWAP2(volume);\r
+ fileid->Seek(6, wxFromCurrent);\r
+ fileid->Read(&matrix, sizeof(unsigned char) * 9);\r
+ fileid->Seek(4, wxFromCurrent);\r
+ fileid->Read(&next_track_ID, sizeof(unsigned long int));\r
+ next_track_ID = BYTE_SWAP4(next_track_ID);\r
+ wxTreeItemId currid = m_tree->AppendItem(parentid,\r
+ wxString::Format(wxT("Rate: %d (%d.%d)"), rate, rate >> 16, rate & 0x0000FFFF),\r
+ m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,\r
+ new OPJMarkerData(wxT("INFO"))\r
+ );\r
+ currid = m_tree->AppendItem(parentid,\r
+ wxString::Format(wxT("Volume: %d (%d.%d)"), volume, volume >> 8, volume & 0x00FF),\r
+ m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,\r
+ new OPJMarkerData(wxT("INFO"))\r
+ );\r
+ currid = m_tree->AppendItem(parentid,\r
+ wxString::Format(wxT("Next track ID: %d"), next_track_ID),\r
+ m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,\r
+ new OPJMarkerData(wxT("INFO"))\r
+ );\r
+ };\r
+ break;\r
+\r
+\r
+ /* Sample Description box */\r
+ case (STSD_BOX): {\r
+\r
+ unsigned long int version, entry_count;\r
+ fileid->Read(&version, sizeof(unsigned long int));\r
+ version = BYTE_SWAP4(version);\r
+ fileid->Read(&entry_count, sizeof(unsigned long int));\r
+ entry_count = BYTE_SWAP4(entry_count);\r
+ wxTreeItemId currid = m_tree->AppendItem(parentid,\r
+ wxString::Format(wxT("Entry count: %d"), entry_count),\r
+ m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,\r
+ new OPJMarkerData(wxT("INFO"), m_tree->m_fname.GetFullPath(), filepoint, filelimit)\r
+ );\r
+ jpeg2000parse(fileid, filepoint + 8, filelimit, parentid, level + 1, scansign, scanpoint);\r
+ };\r
+ break;\r
+\r
+\r
+\r
+ /* MJP2 Sample Description box */\r
+ case (MJP2_BOX): {\r
+\r
+ unsigned short int height, width, depth;\r
+ unsigned long int horizresolution, vertresolution;\r
+ char compressor_name[32];\r
+ fileid->Seek(24, wxFromCurrent);\r
+ fileid->Read(&width, sizeof(unsigned short int));\r
+ width = BYTE_SWAP2(width);\r
+ fileid->Read(&height, sizeof(unsigned short int));\r
+ height = BYTE_SWAP2(height);\r
+ fileid->Read(&horizresolution, sizeof(unsigned long int));\r
+ horizresolution = BYTE_SWAP4(horizresolution);\r
+ fileid->Read(&vertresolution, sizeof(unsigned long int));\r
+ vertresolution = BYTE_SWAP4(vertresolution);\r
+ fileid->Seek(6, wxFromCurrent);\r
+ fileid->Read(compressor_name, sizeof(char) * 32);\r
+ fileid->Read(&depth, sizeof(unsigned short int));\r
+ depth = BYTE_SWAP2(depth);\r
+ wxTreeItemId currid = m_tree->AppendItem(parentid,\r
+ wxString::Format(wxT("Dimensions: %d x %d @ %d bpp"), width, height, depth),\r
+ m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,\r
+ new OPJMarkerData(wxT("INFO"), m_tree->m_fname.GetFullPath(), filepoint, filelimit)\r
+ );\r
+ currid = m_tree->AppendItem(parentid,\r
+ wxString::Format(wxT("Resolution: %d.%d x %d.%d"), horizresolution >> 16, horizresolution & 0x0000FFFF,\r
+ vertresolution >> 16, vertresolution & 0x0000FFFF),\r
+ m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,\r
+ new OPJMarkerData(wxT("INFO"))\r
+ );\r
+ currid = m_tree->AppendItem(parentid,\r
+ wxString::Format(wxT("Compressor: %.32s"), compressor_name),\r
+ m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,\r
+ new OPJMarkerData(wxT("INFO"))\r
+ );\r
+ jpeg2000parse(fileid, filepoint + 78, filelimit, parentid, level + 1, scansign, scanpoint);\r
+\r
+ };\r
+ break;\r
+\r
+ \r
+ /* not yet implemented */\r
+ default:\r
+ break;\r
+\r
+\r
+\r
+ };\r
+\r
+ return (0);\r
+}\r
+\r
+/* jp2 family box signatures */\r
+#define FILE_SIGN ""\r
+#define JP_SIGN "jP\040\040"\r
+#define FTYP_SIGN "ftyp"\r
+#define JP2H_SIGN "jp2h"\r
+#define IHDR_SIGN "ihdr"\r
+#define COLR_SIGN "colr"\r
+#define JP2C_SIGN "jp2c"\r
+#define JP2I_SIGN "jp2i"\r
+#define XML_SIGN "xml\040"\r
+#define UUID_SIGN "uuid"\r
+#define UINF_SIGN "uinf"\r
+#define MOOV_SIGN "moov"\r
+#define MVHD_SIGN "mvhd"\r
+#define TRAK_SIGN "trak"\r
+#define TKHD_SIGN "tkhd"\r
+#define MDIA_SIGN "mdia"\r
+#define MINF_SIGN "minf"\r
+#define STBL_SIGN "stbl"\r
+#define STSD_SIGN "stsd"\r
+#define MJP2_SIGN "mjp2"\r
+#define MDAT_SIGN "mdat"\r
+#define ANY_SIGN ""\r
+#define UNK_SIGN ""\r
+\r
+/* the possible boxes */\r
+struct boxdef j2box[] =\r
+{\r
+/* sign */ {FILE_SIGN,\r
+/* short */ "placeholder for nothing",\r
+/* long */ "Nothing to say",\r
+/* sbox */ 0,\r
+/* req */ {1, 1, 1},\r
+/* ins */ FILE_BOX},\r
+\r
+/* sign */ {JP_SIGN,\r
+/* short */ "JPEG 2000 Signature box",\r
+/* long */ "This box uniquely identifies the file as being part of the JPEG 2000 family of files",\r
+/* sbox */ 0,\r
+/* req */ {1, 1, 1},\r
+/* ins */ FILE_BOX},\r
+\r
+/* sign */ {FTYP_SIGN,\r
+/* short */ "File Type box",\r
+/* long */ "This box specifies file type, version and compatibility information, including specifying if this file "\r
+ "is a conforming JP2 file or if it can be read by a conforming JP2 reader",\r
+/* sbox */ 0,\r
+/* req */ {1, 1, 1},\r
+/* ins */ FILE_BOX},\r
+\r
+/* sign */ {JP2H_SIGN,\r
+/* short */ "JP2 Header box",\r
+/* long */ "This box contains a series of boxes that contain header-type information about the file",\r
+/* sbox */ 1,\r
+/* req */ {1, 1, 1},\r
+/* ins */ FILE_BOX},\r
+\r
+/* sign */ {IHDR_SIGN,\r
+/* short */ "Image Header box",\r
+/* long */ "This box specifies the size of the image and other related fields",\r
+/* sbox */ 0,\r
+/* req */ {1, 1, 1},\r
+/* ins */ JP2H_BOX},\r
+\r
+/* sign */ {COLR_SIGN,\r
+/* short */ "Colour Specification box",\r
+/* long */ "This box specifies the colourspace of the image",\r
+/* sbox */ 0,\r
+/* req */ {1, 1, 1},\r
+/* ins */ JP2H_BOX},\r
+\r
+/* sign */ {JP2C_SIGN,\r
+/* short */ "Contiguous Codestream box",\r
+/* long */ "This box contains the codestream as defined by Annex A",\r
+/* sbox */ 0,\r
+/* req */ {1, 1, 1},\r
+/* ins */ FILE_BOX},\r
+\r
+/* sign */ {JP2I_SIGN,\r
+/* short */ "Intellectual Property box",\r
+/* long */ "This box contains intellectual property information about the image",\r
+/* sbox */ 0,\r
+/* req */ {0, 0, 0},\r
+/* ins */ FILE_BOX},\r
+\r
+/* sign */ {XML_SIGN,\r
+/* short */ "XML box",\r
+/* long */ "This box provides a tool by which vendors can add XML formatted information to a JP2 file",\r
+/* sbox */ 0,\r
+/* req */ {0, 0, 0},\r
+/* ins */ FILE_BOX},\r
+\r
+/* sign */ {UUID_SIGN,\r
+/* short */ "UUID box",\r
+/* long */ "This box provides a tool by which vendors can add additional information to a file "\r
+ "without risking conflict with other vendors",\r
+/* sbox */ 0,\r
+/* req */ {0, 0, 0},\r
+/* ins */ FILE_BOX},\r
+\r
+/* sign */ {UINF_SIGN,\r
+/* short */ "UUID Info box",\r
+/* long */ "This box provides a tool by which a vendor may provide access to additional information associated with a UUID",\r
+/* sbox */ 0,\r
+/* req */ {0, 0, 0},\r
+/* ins */ FILE_BOX},\r
+\r
+/* sign */ {MOOV_SIGN,\r
+/* short */ "Movie box",\r
+/* long */ "This box contains the media data. In video tracks, this box would contain JPEG2000 video frames",\r
+/* sbox */ 1,\r
+/* req */ {1, 1, 1},\r
+/* ins */ FILE_BOX},\r
+\r
+/* sign */ {MVHD_SIGN,\r
+/* short */ "Movie Header box",\r
+/* long */ "This box defines overall information which is media-independent, and relevant to the entire presentation "\r
+ "considered as a whole",\r
+/* sbox */ 0,\r
+/* req */ {1, 1, 1},\r
+/* ins */ MOOV_BOX},\r
+\r
+/* sign */ {TRAK_SIGN,\r
+/* short */ "Track box",\r
+/* long */ "This is a container box for a single track of a presentation. A presentation may consist of one or more tracks",\r
+/* sbox */ 1,\r
+/* req */ {1, 1, 1},\r
+/* ins */ MOOV_BOX},\r
+\r
+/* sign */ {TKHD_SIGN,\r
+/* short */ "Track Header box",\r
+/* long */ "This box specifies the characteristics of a single track. Exactly one Track Header Box is contained in a track",\r
+/* sbox */ 0,\r
+/* req */ {1, 1, 1},\r
+/* ins */ TRAK_BOX},\r
+\r
+/* sign */ {MDIA_SIGN,\r
+/* short */ "Media box",\r
+/* long */ "The media declaration container contains all the objects which declare information about the media data "\r
+ "within a track",\r
+/* sbox */ 1,\r
+/* req */ {1, 1, 1},\r
+/* ins */ TRAK_BOX},\r
+\r
+/* sign */ {MINF_SIGN,\r
+/* short */ "Media Information box",\r
+/* long */ "This box contains all the objects which declare characteristic information of the media in the track",\r
+/* sbox */ 1,\r
+/* req */ {1, 1, 1},\r
+/* ins */ MDIA_BOX},\r
+\r
+/* sign */ {STBL_SIGN,\r
+/* short */ "Sample Table box",\r
+/* long */ "The sample table contains all the time and data indexing of the media samples in a track",\r
+/* sbox */ 1,\r
+/* req */ {1, 1, 1},\r
+/* ins */ MINF_BOX},\r
+\r
+/* sign */ {STSD_SIGN,\r
+/* short */ "Sample Description box",\r
+/* long */ "The sample description table gives detailed information about the coding type used, and any initialization "\r
+ "information needed for that coding",\r
+/* sbox */ 0,\r
+/* req */ {1, 1, 1},\r
+/* ins */ MINF_BOX},\r
+\r
+/* sign */ {MJP2_SIGN,\r
+/* short */ "MJP2 Sample Description box",\r
+/* long */ "The MJP2 sample description table gives detailed information about the coding type used, and any initialization "\r
+ "information needed for that coding",\r
+/* sbox */ 0,\r
+/* req */ {1, 1, 1},\r
+/* ins */ MINF_BOX},\r
+\r
+/* sign */ {MDAT_SIGN,\r
+/* short */ "Media Data box",\r
+/* long */ "The meta-data for a presentation is stored in the single Movie Box which occurs at the top-level of a file",\r
+/* sbox */ 1,\r
+/* req */ {1, 1, 1},\r
+/* ins */ FILE_BOX},\r
+\r
+/* sign */ {ANY_SIGN,\r
+/* short */ "Any box",\r
+/* long */ "All the existing boxes",\r
+/* sbox */ 0,\r
+/* req */ {0, 0, 0},\r
+/* ins */ FILE_BOX},\r
+\r
+/* sign */ {UNK_SIGN,\r
+/* short */ "Unknown Type box",\r
+/* long */ "The signature is not recognised to be that of an existing box",\r
+/* sbox */ 0,\r
+/* req */ {0, 0, 0},\r
+/* ins */ ANY_BOX}\r
+\r
+};\r
+\r
+void OPJParseThread::ParseJP2File(wxFile *fileid, wxFileOffset filepoint, wxFileOffset filelimit, wxTreeItemId parentid)\r
+{\r
+ unsigned long int scanpoint;\r
+\r
+ jpeg2000parse(fileid, filepoint, filelimit, parentid, 0, NULL, &scanpoint);\r
+}\r
+\r
+/* the parsing function itself */\r
+/*\r
+ fileid = fid of the file to scan (you should open it by yourself)\r
+ filepoint = first byte where to start to scan from (usually 0)\r
+ filelimit = first byte where to stop to scan from (usually the file size)\r
+ level = set this to 0\r
+ scansign = signature to scan for (NULL avoids search, returns " " if successful)\r
+ scanpoint = point where the scan signature lies\r
+*/\r
+int OPJParseThread::jpeg2000parse(wxFile *fileid, wxFileOffset filepoint, wxFileOffset filelimit,\r
+ wxTreeItemId parentid, int level, char *scansign, unsigned long int *scanpoint)\r
+{\r
+ unsigned long int LBox = 0x00000000;\r
+ int LBox_read;\r
+ char TBox[5] = "\0\0\0\0";\r
+ int TBox_read;\r
+ __int64 XLBox = 0x0000000000000000;\r
+ int XLBox_read;\r
+ unsigned long int box_length = 0;\r
+ int last_box = 0, box_num = 0;\r
+ int box_type = ANY_BOX;\r
+ unsigned char onebyte[1], twobytes[2], fourbytes[4];\r
+\r
+ /* cycle all over the file */\r
+ box_num = 0;\r
+ last_box = 0;\r
+ while (!last_box) {\r
+\r
+ /* do not exceed file limit */\r
+ if (filepoint >= filelimit)\r
+ return (0);\r
+\r
+ /* seek on file */\r
+ if (fileid->Seek(filepoint, wxFromStart) == wxInvalidOffset)\r
+ return (-1);\r
+\r
+ /* read the mandatory LBox, 4 bytes */\r
+ if (fileid->Read(fourbytes, 4) < 4) {\r
+ WriteText(wxT("Problem reading LBox from the file (file ended?)"));\r
+ return -1;\r
+ };\r
+ LBox = STREAM_TO_UINT32(fourbytes, 0);\r
+\r
+ /* read the mandatory TBox, 4 bytes */\r
+ if (fileid->Read(TBox, 4) < 4) {\r
+ WriteText(wxT("Problem reading TBox from the file (file ended?)"));\r
+ return -1;\r
+ };\r
+\r
+ /* look if scansign is got */\r
+ if ((scansign != NULL) && (memcmp(TBox, scansign, 4) == 0)) {\r
+ memcpy(scansign, " ", 4);\r
+ *scanpoint = filepoint;\r
+\r
+ /* hack/exploit */\r
+ // stop as soon as you find the codebox\r
+ return (0);\r
+\r
+ };\r
+\r
+ /* determine the box type */\r
+ for (box_type = JP_BOX; box_type < UNK_BOX; box_type++)\r
+ if (memcmp(TBox, j2box[box_type].value, 4) == 0)\r
+ break; \r
+\r
+ /* read the optional XLBox, 8 bytes */\r
+ if (LBox == 1) {\r
+\r
+ if (fileid->Read(&XLBox, 8) < 8) {\r
+ WriteText(wxT("Problem reading XLBox from the file (file ended?)"));\r
+ return -1;\r
+ };\r
+ box_length = (unsigned long int) BYTE_SWAP8(XLBox);\r
+\r
+ } else if (LBox == 0x00000000) {\r
+\r
+ /* last box in file */\r
+ last_box = 1; \r
+ box_length = filelimit - filepoint;\r
+\r
+ } else\r
+\r
+ box_length = LBox;\r
+\r
+ /* show box info */\r
+\r
+ // append the marker\r
+ int image, imageSel;\r
+ image = m_tree->TreeCtrlIcon_Folder;\r
+ imageSel = image + 1;\r
+ wxTreeItemId currid = m_tree->AppendItem(parentid,\r
+ wxString::Format(wxT("%03d: %s (0x%04X)"), box_num, TBox,\r
+ ((unsigned long int) TBox[3]) + ((unsigned long int) TBox[2] << 8) +\r
+ ((unsigned long int) TBox[1] << 16) + ((unsigned long int) TBox[0] << 24)\r
+ ),\r
+ image, imageSel,\r
+ new OPJMarkerData(wxT("BOX"), m_tree->m_fname.GetFullPath(), filepoint, filepoint + box_length)\r
+ );\r
+\r
+ // append some info\r
+ image = m_tree->TreeCtrlIcon_File;\r
+ imageSel = image + 1;\r
+\r
+ // box name\r
+ wxTreeItemId subcurrid1 = m_tree->AppendItem(currid,\r
+ wxT("*** ") + wxString(j2box[box_type].name) + wxT(" ***"),\r
+ image, imageSel,\r
+ new OPJMarkerData(wxT("INFO"))\r
+ );\r
+ m_tree->SetItemFont(subcurrid1, *wxITALIC_FONT);\r
+\r
+ // position and length\r
+ wxTreeItemId subcurrid2 = m_tree->AppendItem(currid,\r
+ wxLongLong(filepoint).ToString() + wxT(" > ") + wxLongLong(filepoint + box_length - 1).ToString() + \r
+ wxT(", ") + wxString::Format(wxT("%d + 8 (%d)"), box_length, box_length + 8),\r
+ image, imageSel,\r
+ new OPJMarkerData(wxT("INFO"))\r
+ );\r
+\r
+ /* go deep in the box */\r
+ box_handler_function((int) box_type, fileid, (LBox == 1) ? (filepoint + 16) : (filepoint + 8), filepoint + box_length,\r
+ currid, level, scansign, scanpoint);\r
+\r
+ /* if it's a superbox go inside it */\r
+ if (j2box[box_type].sbox)\r
+ jpeg2000parse(fileid, (LBox == 1) ? (filepoint + 16) : (filepoint + 8), filepoint + box_length,\r
+ currid, level + 1, scansign, scanpoint);\r
+\r
+ /* increment box number and filepoint*/\r
+ box_num++;\r
+ filepoint += box_length;\r
+\r
+ };\r
+\r
+ /* all good */\r
+ return (0);\r
+}\r
+\r