diff --git a/ChangeLog b/ChangeLog index 10bf62e0..218055d9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -5,6 +5,9 @@ What's New for OpenJPEG ! : changed + : added +March 1, 2007 ++ [GB] Zoom capability and decoder settings dialog in OPJViewer; modified JPWL library .dsp project in order to create a library with embedded JPWL functions + February 28, 2007 + [Parvatha] Enabled compression of TIF image format to j2k by tifftoimage() and decompression of codestream to TIF image format using imagetotif(). Modifications in image_to_j2k.c, j2k_to_image.c, convert.c, convert.h * [antonin] fixed a bug in context numerotation that prevented the RESET switch to work correctly : mqc_reset_enc in mqc.c diff --git a/OPJViewer/OPJViewer.dsp b/OPJViewer/OPJViewer.dsp index a388b32b..2188d5dd 100644 --- a/OPJViewer/OPJViewer.dsp +++ b/OPJViewer/OPJViewer.dsp @@ -37,20 +37,20 @@ RSC=rc.exe # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 -# PROP Output_Dir "W32Release" -# PROP Intermediate_Dir "W32Release" +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /G6 /MD /GX /O2 /I "d:\programmi\wxWidgets-2.8.0\lib\vc_lib\msw" /I "d:\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 +# 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" /D "OPJ_HTMLABOUT" /FR /FD /c # ADD BASE RSC /l 0x410 /d "NDEBUG" -# ADD RSC /l 0x409 /i "d:\programmi\wxWidgets-2.8.0\include" /d "NDEBUG" +# ADD RSC /l 0x409 /i "c:\programmi\wxWidgets-2.8.0\include" /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # 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 -# 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:"d:\programmi\wxWidgets-2.8.0\lib\vc_lib" /libpath:"..\jpwl\Release" /IGNORE:4089 +# 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 # SUBTRACT LINK32 /pdb:none !ELSEIF "$(CFG)" == "OPJViewer - Win32 Debug" @@ -62,12 +62,12 @@ LINK32=link.exe # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 -# PROP Output_Dir "W32Debug" -# PROP Intermediate_Dir "W32Debug" +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# 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 +# 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" /D "OPJ_HTMLABOUT" /FR /FD /GZ /c # SUBTRACT CPP /YX # ADD BASE RSC /l 0x410 /d "_DEBUG" # ADD RSC /l 0x410 /i "c:\programmi\wxWidgets-2.8.0\include" /d "_DEBUG" @@ -76,7 +76,7 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.exe # 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 -# 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" +# 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_JPWLd.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" # SUBTRACT LINK32 /pdb:none !ENDIF @@ -158,6 +158,14 @@ SOURCE=.\source\icon5.xpm # End Source File # Begin Source File +SOURCE=.\source\OPJChild.ico +# End Source File +# Begin Source File + +SOURCE=.\source\OPJChild16.xpm +# End Source File +# Begin Source File + SOURCE=.\source\OPJViewer.ico # End Source File # Begin Source File @@ -169,37 +177,5 @@ SOURCE=.\source\OPJViewer.rc SOURCE=.\source\OPJViewer16.xpm # End Source File # End Group -# Begin Group "JPWL" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\jpwl\crc.c -# End Source File -# Begin Source File - -SOURCE=..\jpwl\crc.h -# End Source File -# Begin Source File - -SOURCE=..\jpwl\jpwl.c -# End Source File -# Begin Source File - -SOURCE=..\jpwl\jpwl.h -# End Source File -# Begin Source File - -SOURCE=..\jpwl\jpwl_lib.c -# End Source File -# Begin Source File - -SOURCE=..\jpwl\rs.c -# End Source File -# Begin Source File - -SOURCE=..\jpwl\rs.h -# End Source File -# End Group # End Target # End Project diff --git a/OPJViewer/OPJViewer.iss b/OPJViewer/OPJViewer.iss index 6b324c7a..00f121c9 100644 --- a/OPJViewer/OPJViewer.iss +++ b/OPJViewer/OPJViewer.iss @@ -3,7 +3,7 @@ [Setup] AppName=OPJViewer -AppVerName=OPJViewer 0.1 alpha +AppVerName=OPJViewer 0.2 alpha AppPublisher=OpenJPEG AppPublisherURL=http://www.openjpeg.org AppSupportURL=http://www.openjpeg.org @@ -11,9 +11,17 @@ AppUpdatesURL=http://www.openjpeg.org DefaultDirName={pf}\OPJViewer DefaultGroupName=OPJViewer OutputDir=setup -OutputBaseFilename=OPJViewer01alpha_setup +OutputBaseFilename=OPJViewer02alpha_setup Compression=lzma -SolidCompression=yes +SolidCompression=true +InfoBeforeFile=source\readmebefore.txt +InfoAfterFile=source\readmeafter.txt +LicenseFile=source\license.txt +VersionInfoVersion=0.2.0.0 +VersionInfoCompany=OpenJPEG +VersionInfoDescription=JPEG 2000 viewer +ShowLanguageDialog=yes +SetupIconFile=source\OPJViewer.ico [Languages] Name: english; MessagesFile: compiler:Default.isl @@ -22,13 +30,15 @@ Name: english; MessagesFile: compiler:Default.isl Name: desktopicon; Description: {cm:CreateDesktopIcon}; GroupDescription: {cm:AdditionalIcons}; Flags: unchecked [Files] -Source: W32Release\OPJViewer.exe; DestDir: {app}; Flags: ignoreversion +Source: Release\OPJViewer.exe; DestDir: {app}; Flags: ignoreversion +Source: about\about.htm; DestDir: {app}/about; Flags: ignoreversion +Source: about\opj_logo.png; DestDir: {app}/about; Flags: ignoreversion ; NOTE: Don't use "Flags: ignoreversion" on any shared system files [Icons] -Name: {group}\OPJViewer; Filename: {app}\OPJViewer.exe +Name: {group}\OPJViewer; Filename: {app}\OPJViewer.exe; WorkingDir: {app}; IconIndex: 0 Name: {group}\{cm:UninstallProgram,OPJViewer}; Filename: {uninstallexe} -Name: {userdesktop}\OPJViewer; Filename: {app}\OPJViewer.exe; Tasks: desktopicon +Name: {userdesktop}\OPJViewer; Filename: {app}\OPJViewer.exe; Tasks: desktopicon; WorkingDir: {app}; IconIndex: 0 [Run] -Filename: {app}\OPJViewer.exe; Description: {cm:LaunchProgram,OPJViewer}; Flags: nowait postinstall skipifsilent +Filename: {app}\OPJViewer.exe; Description: {cm:LaunchProgram,OPJViewer}; Flags: nowait postinstall skipifsilent; WorkingDir: {app} diff --git a/OPJViewer/Readme.txt b/OPJViewer/Readme.txt index 58232d82..053bf81a 100644 --- a/OPJViewer/Readme.txt +++ b/OPJViewer/Readme.txt @@ -1,8 +1,6 @@ =============================================================================== - JPEG2000 Visualization Software - - - OPJViewer + JPEG2000 Visualization Software - OPJViewer Version 0.1 alpha diff --git a/OPJViewer/about/about.htm b/OPJViewer/about/about.htm new file mode 100644 index 00000000..88da55b3 --- /dev/null +++ b/OPJViewer/about/about.htm @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + +
+

+
+OPJViewer v0.2 alpha
+A JPEG 2000 image viewer +
+
OpenJPEG
+The OpenJPEG library is an open-source JPEG 2000 codec written in C language. +In addition to the basic codec, various other features are under development, +among them the JP2 and MJ2 (Motion JPEG 2000) file formats, an indexing tool +useful for the JPIP protocol, JPWL-tools for error-resilience, ... +
+OpenJPEG is © 2002-2007 TELE - Université Catholique de Louvain
+OPJViewer is also © 2005-2007 DSPLab - Università degli studi di Perugia +
+ + diff --git a/OPJViewer/about/opj_logo.png b/OPJViewer/about/opj_logo.png new file mode 100644 index 00000000..0f43840a Binary files /dev/null and b/OPJViewer/about/opj_logo.png differ diff --git a/OPJViewer/source/OPJChild.ico b/OPJViewer/source/OPJChild.ico new file mode 100644 index 00000000..7a127189 Binary files /dev/null and b/OPJViewer/source/OPJChild.ico differ diff --git a/OPJViewer/source/OPJChild16.xpm b/OPJViewer/source/OPJChild16.xpm new file mode 100644 index 00000000..48e87963 --- /dev/null +++ b/OPJViewer/source/OPJChild16.xpm @@ -0,0 +1,28 @@ +/* XPM */ +static char *OPJChild16[] = { +/* columns rows colors chars-per-pixel */ +"16 16 6 1", +" c black", +". c #008000", +"X c red", +"o c #800080", +"O c gray100", +"+ c None", +/* pixels */ +"++++++++++++++++", +"+OOOOOOOOOOOOOO+", +"+OooooooooooooO+", +"+OooooooooooooO+", +"+OooOOOOOOOOOoO+", +"+OooO.......OoO+", +"+OooO.......OoO+", +"+OooO..OOO..OoO+", +"+OooO..OXO..OoO+", +"+OooO..OOO..OoO+", +"+OooO.......OoO+", +"+OooO.......OoO+", +"+OooOOOOOOOOOoO+", +"+OooooooooooooO+", +"+OOOOOOOOOOOOOO+", +"++++++++++++++++" +}; diff --git a/OPJViewer/source/OPJViewer.cpp b/OPJViewer/source/OPJViewer.cpp index 3bbf4797..b06ba2d9 100644 --- a/OPJViewer/source/OPJViewer.cpp +++ b/OPJViewer/source/OPJViewer.cpp @@ -93,10 +93,33 @@ // Copyright: (c) 1998-2002 wxWidgets team // License: wxWindows license ///////////////////////////////////////////////////////////////////////////// -#include "OPJViewer.h" +///////////////////////////////////////////////////////////////////////////// +// Name: dialogs.cpp +// Purpose: Common dialogs demo +// Author: Julian Smart +// Modified by: ABX (2004) - adjustements for conditional building + new menu +// Created: 04/01/98 +// RCS-ID: $Id: dialogs.cpp,v 1.163 2006/11/04 10:57:24 VZ Exp $ +// Copyright: (c) Julian Smart +// Licence: wxWindows license +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// +// Name: dnd.cpp +// Purpose: Drag and drop sample +// Author: Vadim Zeitlin +// Modified by: +// Created: 04/01/98 +// RCS-ID: $Id: dnd.cpp,v 1.107 2006/10/30 20:23:41 VZ Exp $ +// Copyright: +// Licence: wxWindows licence +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// +// Name: test.cpp +// Purpose: wxHtml testing example +///////////////////////////////////////////////////////////////////////////// -OPJFrame *frame = NULL; -wxList my_children; + +#include "OPJViewer.h" IMPLEMENT_APP(OPJViewerApp) @@ -110,37 +133,28 @@ int winNumber = 1; bool OPJViewerApp::OnInit(void) { #if wxUSE_UNICODE + wxChar **wxArgv = new wxChar *[argc + 1]; - { - int n; - - for (n = 0; n < argc; n++ ) - { - wxMB2WXbuf warg = wxConvertMB2WX(argv[n]); - wxArgv[n] = wxStrdup(warg); - } - - wxArgv[n] = NULL; + for (int n = 0; n < argc; n++ ) { + wxMB2WXbuf warg = wxConvertMB2WX(argv[n]); + wxArgv[n] = wxStrdup(warg); } + + wxArgv[n] = NULL; + #else // !wxUSE_UNICODE + #define wxArgv argv + #endif // wxUSE_UNICODE/!wxUSE_UNICODE #if wxUSE_CMDLINE_PARSER + static const wxCmdLineEntryDesc cmdLineDesc[] = { { wxCMD_LINE_SWITCH, _T("h"), _T("help"), _T("show this help message"), wxCMD_LINE_VAL_NONE, wxCMD_LINE_OPTION_HELP }, - /*{ wxCMD_LINE_SWITCH, _T("v"), _T("verbose"), _T("be verbose") }, - { wxCMD_LINE_SWITCH, _T("q"), _T("quiet"), _T("be quiet") }, - - { wxCMD_LINE_OPTION, _T("o"), _T("output"), _T("output file") }, - { wxCMD_LINE_OPTION, _T("i"), _T("input"), _T("input dir") }, - { wxCMD_LINE_OPTION, _T("s"), _T("size"), _T("output block size"), - wxCMD_LINE_VAL_NUMBER }, - { wxCMD_LINE_OPTION, _T("d"), _T("date"), _T("output file date"), - wxCMD_LINE_VAL_DATE },*/ { wxCMD_LINE_PARAM, NULL, NULL, _T("input file"), wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL | wxCMD_LINE_PARAM_MULTIPLE }, @@ -154,20 +168,20 @@ bool OPJViewerApp::OnInit(void) wxCMD_LINE_VAL_STRING, wxCMD_LINE_OPTION_MANDATORY | wxCMD_LINE_NEEDS_SEPARATOR);*/ - switch ( parser.Parse() ) - { - case -1: - wxLogMessage(_T("Help was given, terminating.")); - break; + switch (parser.Parse()) { + case -1: + wxLogMessage(wxT("Help was given, terminating.")); + break; - case 0: - ShowCmdLine(parser); - break; + case 0: + ShowCmdLine(parser); + break; - default: - wxLogMessage(_T("Syntax error detected.")); - break; + default: + wxLogMessage(wxT("Syntax error detected.")); + break; } + #endif // wxUSE_CMDLINE_PARSER //wxInitAllImageHandlers(); @@ -179,68 +193,74 @@ bool OPJViewerApp::OnInit(void) wxImage::AddHandler( new wxJP2Handler ); wxImage::AddHandler( new wxMJ2Handler ); #endif + // we use a PNG image in our HTML page + wxImage::AddHandler(new wxPNGHandler); + // set decoding engine parameters + m_reducefactor = 0; + m_qualitylayers = 0; + m_components = 0; +#ifdef USE_JPWL + m_enablejpwl = true; + m_expcomps = JPWL_EXPECTED_COMPONENTS; + m_maxtiles = JPWL_MAXIMUM_TILES; +#endif // USE_JPWL // Create the main frame window - - frame = new OPJFrame(NULL, wxID_ANY, OPJ_APPLICATION_TITLEBAR, wxDefaultPosition, wxSize(800, 600), - wxDEFAULT_FRAME_STYLE | - wxNO_FULL_REPAINT_ON_RESIZE | + OPJFrame *frame = new OPJFrame(NULL, wxID_ANY, OPJ_APPLICATION_TITLEBAR, + wxDefaultPosition, wxSize(800, 600), + wxDEFAULT_FRAME_STYLE | wxNO_FULL_REPAINT_ON_RESIZE | wxHSCROLL | wxVSCROLL); // Give it an icon (this is ignored in MDI mode: uses resources) #ifdef __WXMSW__ - frame->SetIcon(wxIcon(_T("OPJViewer16"))); + frame->SetIcon(wxIcon(wxT("OPJViewer16"))); #endif frame->Show(true); SetTopWindow(frame); + // if there are files on the command line, open them + if (!(m_filelist.IsEmpty())) { + //wxLogMessage(wxT("Habemus files!!!")); + wxArrayString paths, filenames; + for (int f = 0; f < wxGetApp().m_filelist.GetCount(); f++) { + paths.Add(wxFileName(wxGetApp().m_filelist[f]).GetFullPath()); + filenames.Add(wxFileName(wxGetApp().m_filelist[f]).GetFullName()); + } + //wxLogMessage(paths[0]); + frame->OpenFiles(paths, filenames); + } + return true; } void OPJViewerApp::ShowCmdLine(const wxCmdLineParser& parser) { - wxString s = _T("Command line parsed successfully:\nInput files: "); + wxString s = wxT("Command line parsed successfully:\nInput files: "); size_t count = parser.GetParamCount(); - for ( size_t param = 0; param < count; param++ ) - { + for (size_t param = 0; param < count; param++) { s << parser.GetParam(param) << ';'; - m_filelist.Add(parser.GetParam(param)); } - /*s << '\n' - << _T("Verbose:\t") << (parser.Found(_T("v")) ? _T("yes") : _T("no")) << '\n' - << _T("Quiet:\t") << (parser.Found(_T("q")) ? _T("yes") : _T("no")) << '\n'; - - wxString strVal; - long lVal; - wxDateTime dt; - if ( parser.Found(_T("o"), &strVal) ) - s << _T("Output file:\t") << strVal << '\n'; - if ( parser.Found(_T("i"), &strVal) ) - s << _T("Input dir:\t") << strVal << '\n'; - if ( parser.Found(_T("s"), &lVal) ) - s << _T("Size:\t") << lVal << '\n'; - if ( parser.Found(_T("d"), &dt) ) - s << _T("Date:\t") << dt.FormatISODate() << '\n'; - if ( parser.Found(_T("project_name"), &strVal) ) - s << _T("Project:\t") << strVal << '\n';*/ - //wxLogMessage(s); } // OPJFrame events BEGIN_EVENT_TABLE(OPJFrame, wxMDIParentFrame) - EVT_MENU(SASHTEST_ABOUT, OPJFrame::OnAbout) - EVT_MENU(SASHTEST_NEW_WINDOW, OPJFrame::OnFileOpen) + EVT_MENU(OPJFRAME_HELPABOUT, OPJFrame::OnAbout) + EVT_MENU(OPJFRAME_FILEOPEN, OPJFrame::OnFileOpen) EVT_SIZE(OPJFrame::OnSize) - EVT_MENU(SASHTEST_QUIT, OPJFrame::OnQuit) - EVT_MENU(SASHTEST_TOGGLE_WINDOW, OPJFrame::OnToggleWindow) - EVT_SASH_DRAGGED_RANGE(ID_WINDOW_TOP, ID_WINDOW_BOTTOM, OPJFrame::OnSashDrag) + EVT_MENU(OPJFRAME_FILEEXIT, OPJFrame::OnQuit) + EVT_MENU(OPJFRAME_FILECLOSE, OPJFrame::OnClose) + EVT_MENU(OPJFRAME_VIEWZOOM, OPJFrame::OnZoom) + EVT_MENU(OPJFRAME_VIEWFIT, OPJFrame::OnFit) + EVT_MENU(OPJFRAME_FILETOGGLE, OPJFrame::OnToggleWindow) + EVT_MENU(OPJFRAME_SETSDECO, OPJFrame::OnSetsDeco) + EVT_SASH_DRAGGED_RANGE(OPJFRAME_BROWSEWIN, OPJFRAME_LOGWIN, OPJFrame::OnSashDrag) EVT_NOTEBOOK_PAGE_CHANGED(LEFT_NOTEBOOK_ID, OPJFrame::OnNotebook) END_EVENT_TABLE() @@ -252,24 +272,44 @@ OPJFrame::OPJFrame(wxWindow *parent, const wxWindowID id, const wxString& title, // file menu and its items wxMenu *file_menu = new wxMenu; - file_menu->Append(SASHTEST_NEW_WINDOW, wxT("&Open\tCtrl+O")); - file_menu->SetHelpString(SASHTEST_NEW_WINDOW, wxT("Open one or more files")); + file_menu->Append(OPJFRAME_FILEOPEN, wxT("&Open\tCtrl+O")); + file_menu->SetHelpString(OPJFRAME_FILEOPEN, wxT("Open one or more files")); - file_menu->Append(SASHTEST_TOGGLE_WINDOW, wxT("&Toggle browser\tCtrl+T")); - file_menu->SetHelpString(SASHTEST_TOGGLE_WINDOW, wxT("Toggle the left browsing pane")); + file_menu->Append(OPJFRAME_FILETOGGLE, wxT("&Toggle browser\tCtrl+T")); + file_menu->SetHelpString(OPJFRAME_FILETOGGLE, wxT("Toggle the left browsing pane")); - file_menu->Append(SASHTEST_QUIT, wxT("&Exit\tCtrl+Q")); - file_menu->SetHelpString(SASHTEST_QUIT, wxT("Quit this program")); + file_menu->Append(OPJFRAME_FILECLOSE, wxT("&Close\tCtrl+C")); + file_menu->SetHelpString(OPJFRAME_FILECLOSE, wxT("Close current image")); + + file_menu->Append(OPJFRAME_FILEEXIT, wxT("&Exit\tCtrl+Q")); + file_menu->SetHelpString(OPJFRAME_FILEEXIT, wxT("Quit this program")); + + // view menu and its items + wxMenu *view_menu = new wxMenu; + + view_menu->Append(OPJFRAME_VIEWZOOM, wxT("&Zoom\tCtrl+Z")); + view_menu->SetHelpString(OPJFRAME_VIEWZOOM, wxT("Rescale the image")); + + view_menu->Append(OPJFRAME_VIEWFIT, wxT("Zoom to &fit\tCtrl+F")); + view_menu->SetHelpString(OPJFRAME_VIEWFIT, wxT("Fit the image in canvas")); + + // settings menu and its items + wxMenu *sets_menu = new wxMenu; + + sets_menu->Append(OPJFRAME_SETSDECO, wxT("&Decoder\tCtrl+D")); + sets_menu->SetHelpString(OPJFRAME_SETSDECO, wxT("Decoder settings")); // help menu and its items wxMenu *help_menu = new wxMenu; - help_menu->Append(SASHTEST_ABOUT, wxT("&About\tF1")); - help_menu->SetHelpString(SASHTEST_ABOUT, wxT("Basic info on the program")); + help_menu->Append(OPJFRAME_HELPABOUT, wxT("&About\tF1")); + help_menu->SetHelpString(OPJFRAME_HELPABOUT, wxT("Basic info on the program")); // the whole menubar wxMenuBar *menu_bar = new wxMenuBar; menu_bar->Append(file_menu, wxT("&File")); + menu_bar->Append(view_menu, wxT("&View")); + menu_bar->Append(sets_menu, wxT("&Settings")); menu_bar->Append(help_menu, wxT("&Help")); // Associate the menu bar with the frame @@ -279,7 +319,7 @@ OPJFrame::OPJFrame(wxWindow *parent, const wxWindowID id, const wxString& title, CreateStatusBar(); // the logging window - loggingWindow = new wxSashLayoutWindow(this, ID_WINDOW_BOTTOM, + loggingWindow = new wxSashLayoutWindow(this, OPJFRAME_LOGWIN, wxDefaultPosition, wxSize(400, 130), wxNO_BORDER | wxSW_3D | wxCLIP_CHILDREN ); @@ -307,15 +347,18 @@ OPJFrame::OPJFrame(wxWindow *parent, const wxWindowID id, const wxString& title, // create the text control of the browser m_textCtrlbrowse = new wxTextCtrl(m_bookCtrlbottom, wxID_ANY, wxT(""), wxDefaultPosition, wxDefaultSize, - wxTE_MULTILINE | wxSUNKEN_BORDER | wxTE_READONLY + wxTE_MULTILINE | wxSUNKEN_BORDER | wxTE_READONLY | wxTE_RICH ); - m_textCtrlbrowse->SetValue(_T("Browsing window\n")); + wxFont *browsefont = new wxFont(wxNORMAL_FONT->GetPointSize(), + wxFONTFAMILY_TELETYPE, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL); + m_textCtrlbrowse->SetDefaultStyle(wxTextAttr(wxNullColour, wxNullColour, *browsefont)); + m_textCtrlbrowse->AppendText(wxT("Browsing window\n")); // add it the notebook - m_bookCtrlbottom->AddPage(m_textCtrlbrowse, wxT("Peek")); + m_bookCtrlbottom->AddPage(m_textCtrlbrowse, wxT("Peek"), false); // the browser window - markerTreeWindow = new wxSashLayoutWindow(this, ID_WINDOW_LEFT1, + markerTreeWindow = new wxSashLayoutWindow(this, OPJFRAME_BROWSEWIN, wxDefaultPosition, wxSize(300, 30), wxNO_BORDER | wxSW_3D | wxCLIP_CHILDREN ); @@ -331,8 +374,6 @@ OPJFrame::OPJFrame(wxWindow *parent, const wxWindowID id, const wxString& title, wxDefaultPosition, wxDefaultSize, wxBK_TOP); - -#if wxUSE_LOG #ifdef __WXMOTIF__ // For some reason, we get a memcpy crash in wxLogStream::DoLogStream // on gcc/wxMotif, if we use wxLogTextCtl. Maybe it's just gcc? @@ -342,18 +383,10 @@ OPJFrame::OPJFrame(wxWindow *parent, const wxWindowID id, const wxString& title, wxLogTextCtrl *logWindow = new wxLogTextCtrl(m_textCtrl); delete wxLog::SetActiveTarget(logWindow); #endif -#endif // wxUSE_LOG - // if there are files on the command line, open them - /*if (!wxGetApp().m_filelist.IsEmpty()) { - wxLogMessage(wxT("Habemus files!!!")); - wxArrayString paths, filenames; - for (int f = 0; f < wxGetApp().m_filelist.GetCount(); f++) { - paths.Add(wxFileName(wxGetApp().m_filelist[f]).GetFullPath()); - filenames.Add(wxFileName(wxGetApp().m_filelist[f]).GetFullName()); - } - OpenFiles(paths, filenames); - }*/ + // associate drop targets with the controls + SetDropTarget(new OPJDnDFile(this)); + } // this is the frame destructor @@ -385,7 +418,7 @@ void OPJFrame::OnNotebook(wxNotebookEvent& event) m_childhash[childnum]->Activate(); - wxLogMessage(wxString::Format(wxT("Selection changed (now %d --> %d)"), childnum, m_childhash[childnum]->m_winnumber)); + //wxLogMessage(wxT("Selection changed (now %d --> %d)"), childnum, m_childhash[childnum]->m_winnumber); } @@ -395,14 +428,138 @@ void OPJFrame::Resize(int number) wxSize size = GetClientSize(); } +void OPJFrame::OnSetsDeco(wxCommandEvent& event) +{ + OPJDecoderDialog dialog(this, event.GetId()); + + if (dialog.ShowModal() == wxID_OK) { + + // load settings + wxGetApp().m_reducefactor = dialog.m_reduceCtrl->GetValue(); + wxGetApp().m_qualitylayers = dialog.m_layerCtrl->GetValue(); + wxGetApp().m_components = dialog.m_numcompsCtrl->GetValue(); +#ifdef USE_JPWL + wxGetApp().m_enablejpwl = dialog.m_enablejpwlCheck->GetValue(); + wxGetApp().m_expcomps = dialog.m_expcompsCtrl->GetValue(); + wxGetApp().m_maxtiles = dialog.m_maxtilesCtrl->GetValue(); +#endif // USE_JPWL + + }; +} + void OPJFrame::OnQuit(wxCommandEvent& WXUNUSED(event)) { Close(true); } +void OPJFrame::OnClose(wxCommandEvent& WXUNUSED(event)) +{ + // current frame + OPJChildFrame *currframe = (OPJChildFrame *) GetActiveChild(); + + if (!currframe) + return; + + wxCloseEvent e; + currframe->OnClose(e); +} + +void OPJFrame::OnFit(wxCommandEvent& WXUNUSED(event)) +{ + // current child + OPJChildFrame *currchild = (OPJChildFrame *) GetActiveChild(); + if (!currchild) + return; + + // current canvas + OPJCanvas *currcanvas = currchild->m_canvas; + + // find a fit-to-width zoom + int zooml, wzooml, hzooml; + wxSize clientsize = currcanvas->GetClientSize(); + wzooml = (int) ceil(100.0 * (double) (clientsize.GetWidth() - 2 * OPJ_CANVAS_BORDER) / (double) (currcanvas->m_image100.GetWidth())); + hzooml = (int) ceil(100.0 * (double) (clientsize.GetHeight() - 2 * OPJ_CANVAS_BORDER) / (double) (currcanvas->m_image100.GetHeight())); + zooml = wxMin(100, wxMin(wzooml, hzooml)); + + // fit to width + Rescale(zooml, currchild); +} + +void OPJFrame::OnZoom(wxCommandEvent& WXUNUSED(event)) +{ + // current frame + OPJChildFrame *currframe = (OPJChildFrame *) GetActiveChild(); + + if (!currframe) + return; + + // get the preferred zoom + long zooml = wxGetNumberFromUser(wxT("Choose a scale between 5% and 300%"), + wxT("Zoom (%)"), + wxT("Image scale"), + currframe->m_canvas->m_zooml, 5, 300, NULL, wxDefaultPosition); + + // rescale current frame image if necessary + if (zooml >= 5) { + Rescale(zooml, currframe); + wxLogMessage(wxT("zoom to %d%%"), zooml); + } +} + +void OPJFrame::Rescale(int zooml, OPJChildFrame *currframe) +{ + wxImage new_image = currframe->m_canvas->m_image100.ConvertToImage(); + if (zooml != 100) + new_image.Rescale((int) ((double) zooml * (double) new_image.GetWidth() / 100.0), + (int) ((double) zooml * (double) new_image.GetHeight() / 100.0), + wxIMAGE_QUALITY_NORMAL); + currframe->m_canvas->m_image = wxBitmap(new_image); + currframe->m_canvas->SetScrollbars(20, + 20, + (int)(0.5 + (double) new_image.GetWidth() / 20.0), + (int)(0.5 + (double) new_image.GetHeight() / 20.0) + ); + currframe->m_canvas->Refresh(); + + // update zoom + currframe->m_canvas->m_zooml = zooml; +} + + // about window for the frame void OPJFrame::OnAbout(wxCommandEvent& WXUNUSED(event)) { +#ifdef OPJ_HTMLABOUT + + wxBoxSizer *topsizer; + wxHtmlWindow *html; + wxDialog dlg(this, wxID_ANY, wxString(_("About"))); + + topsizer = new wxBoxSizer(wxVERTICAL); + + html = new wxHtmlWindow(&dlg, wxID_ANY, wxDefaultPosition, wxSize(350, 250), wxHW_SCROLLBAR_NEVER); + html->SetBorders(0); + html->LoadPage(wxT("about/about.htm")); + //html->SetPage("Hello, world!"); + html->SetSize(html->GetInternalRepresentation()->GetWidth(), + html->GetInternalRepresentation()->GetHeight()); + + topsizer->Add(html, 1, wxALL, 10); + + topsizer->Add(new wxStaticLine(&dlg, wxID_ANY), 0, wxEXPAND | wxLEFT | wxRIGHT, 10); + + wxButton *bu1 = new wxButton(&dlg, wxID_OK, wxT("OK")); + bu1->SetDefault(); + + topsizer->Add(bu1, 0, wxALL | wxALIGN_RIGHT, 15); + + dlg.SetSizer(topsizer); + topsizer->Fit(&dlg); + + dlg.ShowModal(); + +#else + wxMessageBox(wxString::Format(OPJ_APPLICATION_TITLEBAR wxT("\n\n") wxT("Built with %s and OpenJPEG ") @@ -411,28 +568,25 @@ void OPJFrame::OnAbout(wxCommandEvent& WXUNUSED(event)) wxT("\nRunning under %s\n\n") OPJ_APPLICATION_COPYRIGHT, wxVERSION_STRING, - wxGetOsDescription().c_str() - ), + wxGetOsDescription().c_str()), wxT("About ") OPJ_APPLICATION_NAME, wxOK | wxICON_INFORMATION, this ); + +#endif + } void OPJFrame::OnToggleWindow(wxCommandEvent& WXUNUSED(event)) { if (markerTreeWindow->IsShown()) - { markerTreeWindow->Show(false); - } else - { markerTreeWindow->Show(true); - } -#if wxUSE_MDI_ARCHITECTURE + wxLayoutAlgorithm layout; layout.LayoutMDIFrame(this); -#endif // wxUSE_MDI_ARCHITECTURE } void OPJFrame::OnSashDrag(wxSashEvent& event) @@ -440,24 +594,21 @@ void OPJFrame::OnSashDrag(wxSashEvent& event) if (event.GetDragStatus() == wxSASH_STATUS_OUT_OF_RANGE) return; - switch (event.GetId()) - { - case ID_WINDOW_LEFT1: - { - markerTreeWindow->SetDefaultSize(wxSize(event.GetDragRect().width, 1000)); - break; - } - case ID_WINDOW_BOTTOM: - { - loggingWindow->SetDefaultSize(wxSize(1000, event.GetDragRect().height)); - break; - } + switch (event.GetId()) { + case OPJFRAME_BROWSEWIN: + { + markerTreeWindow->SetDefaultSize(wxSize(event.GetDragRect().width, 1000)); + break; + } + case OPJFRAME_LOGWIN: + { + loggingWindow->SetDefaultSize(wxSize(1000, event.GetDragRect().height)); + break; + } } -#if wxUSE_MDI_ARCHITECTURE wxLayoutAlgorithm layout; layout.LayoutMDIFrame(this); -#endif // wxUSE_MDI_ARCHITECTURE // Leaves bits of itself behind sometimes GetClientWindow()->Refresh(); @@ -467,58 +618,44 @@ void OPJFrame::OnSashDrag(wxSashEvent& event) void OPJFrame::OpenFiles(wxArrayString paths, wxArrayString filenames) { - size_t count = paths.GetCount(); - for ( size_t n = 0; n < count; n++ ) - { - wxString msg, s; - s.Printf(_T("File %d: %s (%s)\n"), - (int)n, paths[n].c_str(), filenames[n].c_str()); + size_t count = paths.GetCount(); + for (size_t n = 0; n < count; n++) { - msg += s; - //s.Printf(_T("Filter index: %d"), dialog.GetFilterIndex()); - msg += s; + wxString msg, s; + s.Printf(_T("File %d: %s (%s)\n"), (int)n, paths[n].c_str(), filenames[n].c_str()); - /*wxMessageDialog dialog2(this, msg, _T("Selected files")); - dialog2.ShowModal();*/ + msg += s; - // Make another frame, containing a canvas - OPJChildFrame *subframe = new OPJChildFrame(frame, - paths[n], - winNumber, - _T("Canvas Frame"), - wxDefaultPosition, wxSize(300, 300), - wxDEFAULT_FRAME_STYLE | - wxNO_FULL_REPAINT_ON_RESIZE); - m_childhash[winNumber] = subframe; + /*wxMessageDialog dialog2(this, msg, _T("Selected files")); + dialog2.ShowModal();*/ - // create own marker tree - long tstyle = wxTR_DEFAULT_STYLE | wxSUNKEN_BORDER | - #ifndef NO_VARIABLE_HEIGHT - wxTR_HAS_VARIABLE_ROW_HEIGHT /*|*/ - #endif - /*wxTR_EDIT_LABELS*/; + // Make another frame, containing a canvas + OPJChildFrame *subframe = new OPJChildFrame(this, + paths[n], + winNumber, + wxT("Canvas Frame"), + wxDefaultPosition, wxSize(300, 300), + wxDEFAULT_FRAME_STYLE | wxNO_FULL_REPAINT_ON_RESIZE + ); + m_childhash[winNumber] = subframe; - m_treehash[winNumber] = new OPJMarkerTree(m_bookCtrl, paths[n], wxT("Parsing..."), TreeTest_Ctrl, - wxDefaultPosition, wxDefaultSize, - tstyle); + // create own marker tree + m_treehash[winNumber] = new OPJMarkerTree(m_bookCtrl, paths[n], wxT("Parsing..."), TreeTest_Ctrl, + wxDefaultPosition, wxDefaultSize, + wxTR_DEFAULT_STYLE | wxSUNKEN_BORDER + ); - m_bookCtrl->AddPage(m_treehash[winNumber], - wxString::Format(wxT("%u"), winNumber), false); + m_bookCtrl->AddPage(m_treehash[winNumber], wxString::Format(wxT("%u"), winNumber), false); - for (int p = 0; p < m_bookCtrl->GetPageCount(); p++) { - - if (m_bookCtrl->GetPageText(p) == wxString::Format(wxT("%u"), winNumber)) { - m_bookCtrl->ChangeSelection(p); - break; - } - - } - - winNumber++; - + for (int p = 0; p < m_bookCtrl->GetPageCount(); p++) { + if (m_bookCtrl->GetPageText(p) == wxString::Format(wxT("%u"), winNumber)) { + m_bookCtrl->ChangeSelection(p); + break; + } } - + winNumber++; + } } void OPJFrame::OnFileOpen(wxCommandEvent& WXUNUSED(event)) @@ -533,15 +670,13 @@ void OPJFrame::OnFileOpen(wxCommandEvent& WXUNUSED(event)) wxEmptyString, wxEmptyString, wildcards, wxFD_OPEN|wxFD_MULTIPLE); - if (dialog.ShowModal() == wxID_OK) - { + if (dialog.ShowModal() == wxID_OK) { wxArrayString paths, filenames; dialog.GetPaths(paths); dialog.GetFilenames(filenames); OpenFiles(paths, filenames); - } } @@ -558,14 +693,17 @@ OPJCanvas::OPJCanvas(wxFileName fname, wxWindow *parent, const wxPoint& pos, con SetBackgroundColour(OPJ_CANVAS_COLOUR); m_fname = fname; + m_childframe = (OPJChildFrame *) parent; OPJDecoThread *dthread = CreateDecoThread(); if (dthread->Run() != wxTHREAD_NO_ERROR) wxLogMessage(wxT("Can't start deco thread!")); else - wxLogMessage(_T("New deco thread started.")); + wxLogMessage(wxT("New deco thread started.")); + // 100% zoom + m_zooml = 100; } OPJDecoThread *OPJCanvas::CreateDecoThread(void) @@ -584,10 +722,6 @@ OPJDecoThread *OPJCanvas::CreateDecoThread(void) // Define the repainting behaviour void OPJCanvas::OnDraw(wxDC& dc) { - /*dc.SetFont(*wxSWISS_FONT); - dc.SetPen(*wxBLACK_PEN); - dc.DrawText(_T("Image drawing canvas"), 10, 10); - dc.DrawLine(8, 22, 300, 22);*/ if (m_image.Ok()) { dc.DrawBitmap(m_image, OPJ_CANVAS_BORDER, OPJ_CANVAS_BORDER); } else { @@ -595,30 +729,6 @@ void OPJCanvas::OnDraw(wxDC& dc) dc.SetPen(*wxBLACK_PEN); dc.DrawText(_T("Decoding image, please wait..."), 40, 50); } - - /*dc.SetFont(*wxSWISS_FONT); - dc.SetPen(*wxGREEN_PEN); - dc.DrawLine(0, 0, 200, 200); - dc.DrawLine(200, 0, 0, 200); - - dc.SetBrush(*wxCYAN_BRUSH); - dc.SetPen(*wxRED_PEN); - dc.DrawRectangle(100, 100, 100, 50); - dc.DrawRoundedRectangle(150, 150, 100, 50, 20); - - dc.DrawEllipse(250, 250, 100, 50); -#if wxUSE_SPLINES - dc.DrawSpline(50, 200, 50, 100, 200, 10); -#endif // wxUSE_SPLINES - dc.DrawLine(50, 230, 200, 230); - dc.DrawText(_T("This is a test string"), 50, 230); - - wxPoint points[3]; - points[0].x = 200; points[0].y = 300; - points[1].x = 100; points[1].y = 400; - points[2].x = 300; points[2].y = 400; - - dc.DrawPolygon(3, points);*/ } // This implements a tiny doodling program! Drag the mouse using @@ -630,9 +740,8 @@ void OPJCanvas::OnEvent(wxMouseEvent& event) wxPoint pt(event.GetLogicalPosition(dc)); - if (xpos > -1 && ypos > -1 && event.Dragging()) - { - dc.SetPen(*wxBLACK_PEN); + if ((xpos > -1) && (ypos > -1) && event.Dragging()) { + dc.SetPen(*wxRED_PEN); dc.DrawLine(xpos, ypos, pt.x, pt.y); } xpos = pt.x; @@ -641,13 +750,11 @@ void OPJCanvas::OnEvent(wxMouseEvent& event) void OPJFrame::OnSize(wxSizeEvent& WXUNUSED(event)) { -#if wxUSE_MDI_ARCHITECTURE wxLayoutAlgorithm layout; layout.LayoutMDIFrame(this); -#endif // wxUSE_MDI_ARCHITECTURE } -// Note that SASHTEST_NEW_WINDOW and SASHTEST_ABOUT commands get passed +// Note that OPJFRAME_FILEOPEN and OPJFRAME_HELPABOUT commands get passed // to the parent window for processing, so no need to // duplicate event handlers here. @@ -655,7 +762,7 @@ BEGIN_EVENT_TABLE(OPJChildFrame, wxMDIChildFrame) /*EVT_MENU(SASHTEST_CHILD_QUIT, OPJChildFrame::OnQuit)*/ EVT_CLOSE(OPJChildFrame::OnClose) EVT_SET_FOCUS(OPJChildFrame::OnGotFocus) - /*EVT_KILL_FOCUS(OPJChildFrame::OnLostFocus)*/ + EVT_KILL_FOCUS(OPJChildFrame::OnLostFocus) END_EVENT_TABLE() OPJChildFrame::OPJChildFrame(OPJFrame *parent, wxFileName fname, int winnumber, const wxString& title, const wxPoint& pos, const wxSize& size, @@ -664,7 +771,7 @@ const long style): { m_frame = (OPJFrame *) parent; m_canvas = NULL; - my_children.Append(this); + //my_children.Append(this); m_fname = fname; m_winnumber = winnumber; SetTitle(wxString::Format(_T("%d: "), m_winnumber) + m_fname.GetFullName()); @@ -672,38 +779,11 @@ const long style): // Give it an icon (this is ignored in MDI mode: uses resources) #ifdef __WXMSW__ - SetIcon(wxIcon(_T("sashtest_icn"))); + SetIcon(wxIcon(wxT("OPJChild16"))); #endif -#if wxUSE_STATUSBAR // Give it a status line - //CreateStatusBar(); -#endif // wxUSE_STATUSBAR - - // Make a menubar - /*wxMenu *file_menu = new wxMenu; - - file_menu->Append(SASHTEST_NEW_WINDOW, _T("&Open\tCtrl+O")); - file_menu->Append(SASHTEST_CHILD_QUIT, _T("&Close\tCtrl+C")); - file_menu->Append(SASHTEST_QUIT, _T("&Exit\tCtrl+Q")); - - wxMenu *option_menu = new wxMenu; - - // Dummy option - option_menu->Append(SASHTEST_REFRESH, _T("&Refresh picture")); - - wxMenu *help_menu = new wxMenu; - help_menu->Append(SASHTEST_ABOUT, _T("&About\tF1")); - - wxMenuBar *menu_bar = new wxMenuBar; - - menu_bar->Append(file_menu, _T("&File")); - menu_bar->Append(option_menu, _T("&Options")); - menu_bar->Append(help_menu, _T("&Help")); - - // Associate the menu bar with the frame - SetMenuBar(menu_bar);*/ - + /*CreateStatusBar();*/ int width, height; GetClientSize(&width, &height); @@ -712,43 +792,21 @@ const long style): canvas->SetCursor(wxCursor(wxCURSOR_PENCIL)); m_canvas = canvas; - // Give it scrollbars + // Give it scrollbars canvas->SetScrollbars(20, 20, 5, 5); Show(true); Maximize(true); - - /*wxSize gsize = m_frame->m_bookCtrl->GetClientSize(); - m_frame->m_treehash[m_winnumber]->SetSize(0, 0, gsize.x, gsize.y);*/ - - /*m_frame->Resize(m_winnumber);*/ - /*m_frame->m_treehash[0]->Show(false); - m_frame->m_treehash[m_winnumber]->Show(true);*/ - /*m_frame->Resize(m_winnumber);*/ - /*wxLogError(wxString::Format(wxT("Created tree %d (0x%x)"), m_winnumber, m_frame->m_treehash[m_winnumber]));*/ } OPJChildFrame::~OPJChildFrame(void) { - my_children.DeleteObject(this); + //my_children.DeleteObject(this); } -/*void OPJChildFrame::OnQuit(wxCommandEvent& WXUNUSED(event)) -{ - for (int p = 0; p < m_frame->m_bookCtrl->GetPageCount(); p++) { - - if (m_frame->m_bookCtrl->GetPageText(p) == wxString::Format(wxT("%u"), m_winnumber)) { - m_frame->m_bookCtrl->DeletePage(p);; - break; - } - - } - - Close(true); -}*/ void OPJChildFrame::OnClose(wxCloseEvent& event) { @@ -762,7 +820,7 @@ void OPJChildFrame::OnClose(wxCloseEvent& event) } Destroy(); - wxLogMessage(wxString::Format(wxT("Closed: %d"), m_winnumber)); + wxLogMessage(wxT("Closed: %d"), m_winnumber); } @@ -787,14 +845,13 @@ void OPJChildFrame::OnGotFocus(wxFocusEvent& event) } - wxLogMessage(wxString::Format(wxT("Got focus: %d (%x)"), m_winnumber, event.GetWindow())); + //wxLogMessage(wxT("Got focus: %d (%x)"), m_winnumber, event.GetWindow()); } -/*void OPJChildFrame::OnLostFocus(wxFocusEvent& event) +void OPJChildFrame::OnLostFocus(wxFocusEvent& event) { - wxLogMessage(wxString::Format(wxT("Lost focus: %d (%x)"), m_winnumber, event.GetWindow())); - -}*/ + //wxLogMessage(wxT("Lost focus: %d (%x)"), m_winnumber, event.GetWindow()); +} #if USE_GENERIC_TREECTRL BEGIN_EVENT_TABLE(OPJMarkerTree, wxGenericTreeCtrl) @@ -826,7 +883,7 @@ BEGIN_EVENT_TABLE(OPJMarkerTree, wxTreeCtrl) // EVT_TREE_ITEM_MENU is the preferred event for creating context menus // on a tree control, because it includes the point of the click or item, // meaning that no additional placement calculations are required. - /*EVT_TREE_ITEM_MENU(TreeTest_Ctrl, OPJMarkerTree::OnItemMenu)*/ + EVT_TREE_ITEM_MENU(TreeTest_Ctrl, OPJMarkerTree::OnItemMenu) /*EVT_TREE_ITEM_RIGHT_CLICK(TreeTest_Ctrl, OPJMarkerTree::OnItemRClick)*/ /*EVT_RIGHT_DOWN(OPJMarkerTree::OnRMouseDown) @@ -842,8 +899,7 @@ IMPLEMENT_DYNAMIC_CLASS(OPJMarkerTree, wxTreeCtrl) #endif OPJMarkerTree::OPJMarkerTree(wxWindow *parent, wxFileName fname, wxString name, const wxWindowID id, - const wxPoint& pos, const wxSize& size, - long style) + const wxPoint& pos, const wxSize& size, long style) : wxTreeCtrl(parent, id, pos, size, style) { m_reverseSort = false; @@ -863,17 +919,16 @@ OPJMarkerTree::OPJMarkerTree(wxWindow *parent, wxFileName fname, wxString name, if (pthread->Run() != wxTHREAD_NO_ERROR) wxLogMessage(wxT("Can't start parse thread!")); else - wxLogMessage(_T("New parse thread started.")); + wxLogMessage(wxT("New parse thread started.")); } void OPJMarkerTree::CreateImageList(int size) { - if ( size == -1 ) - { + if (size == -1) { SetImageList(NULL); return; } - if ( size == 0 ) + if (size == 0) size = m_imageSize; else m_imageSize = size; @@ -891,14 +946,10 @@ void OPJMarkerTree::CreateImageList(int size) icons[4] = wxIcon(icon5_xpm); int sizeOrig = icons[0].GetWidth(); - for ( size_t i = 0; i < WXSIZEOF(icons); i++ ) - { - if ( size == sizeOrig ) - { + for (size_t i = 0; i < WXSIZEOF(icons); i++) { + if (size == sizeOrig) { images->Add(icons[i]); - } - else - { + } else { images->Add(wxBitmap(wxBitmap(icons[i]).ConvertToImage().Rescale(size, size))); } } @@ -909,8 +960,7 @@ void OPJMarkerTree::CreateImageList(int size) #if USE_GENERIC_TREECTRL || !defined(__WXMSW__) void OPJMarkerTree::CreateButtonsImageList(int size) { - if ( size == -1 ) - { + if ( size == -1 ) { SetButtonsImageList(NULL); return; } @@ -926,15 +976,11 @@ void OPJMarkerTree::CreateButtonsImageList(int size) icons[2] = wxIcon(icon5_xpm); // open icons[3] = wxIcon(icon5_xpm); // open, selected - for ( size_t i = 0; i < WXSIZEOF(icons); i++ ) - { + for ( size_t i = 0; i < WXSIZEOF(icons); i++ ) { int sizeOrig = icons[i].GetWidth(); - if ( size == sizeOrig ) - { + if ( size == sizeOrig ) { images->Add(icons[i]); - } - else - { + } else { images->Add(wxBitmap(wxBitmap(icons[i]).ConvertToImage().Rescale(size, size))); } } @@ -1147,9 +1193,9 @@ void OPJMarkerTree::LogEvent(const wxChar *name, const wxTreeEvent& event) wxTreeItemId item = event.GetItem(); wxString text; if ( item.IsOk() ) - text << _T('"') << GetItemText(item).c_str() << _T('"'); + text << wxT('"') << GetItemText(item).c_str() << wxT('"'); else - text = _T("invalid item"); + text = wxT("invalid item"); wxLogMessage(wxT("%s(%s)"), name, text.c_str()); } @@ -1219,8 +1265,8 @@ void OPJMarkerTree::OnItemExpanding(wxTreeEvent& event) void OPJMarkerTree::OnSelChanged(wxTreeEvent& event) { -#define BUNCH_LINESIZE 24 -#define BUNCH_NUMLINES 6 +#define BUNCH_LINESIZE 16 +#define BUNCH_NUMLINES 7 wxTreeItemId item = event.GetItem(); OPJMarkerData* data = (OPJMarkerData *) GetItemData(item); @@ -1230,13 +1276,9 @@ void OPJMarkerTree::OnSelChanged(wxTreeEvent& event) m_peektextCtrl->Clear(); - /*wxTextAttr myattr = m_peektextCtrl->GetDefaultStyle(); - myattr.SetFont(wxFont(10, wxFONTFAMILY_TELETYPE, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL)); - m_peektextCtrl->SetDefaultStyle(myattr);*/ - - text << wxString::Format(wxT("Selected... (%s -> %s, %s, %d, %d)"), + /*text << wxString::Format(wxT("Selected... (%s -> %s, %s, %d, %d)"), text.c_str(), data->GetDesc1(), data->GetDesc2(), - data->m_start, data->m_length) << wxT("\n"); + data->m_start, data->m_length) << wxT("\n");*/ // open the file and browse a little wxFile *fp = new wxFile(m_fname.GetFullPath().c_str(), wxFile::read); @@ -1248,10 +1290,11 @@ void OPJMarkerTree::OnSelChanged(wxTreeEvent& event) int max_read = wxMin(WXSIZEOF(buffer), data->m_length - data->m_start + 1); fp->Read(buffer, max_read); + // write the file data between start and stop pos = 0; for (l = 0; l < BUNCH_NUMLINES; l++) { - text << wxString::Format(wxT("%08d:"), data->m_start + pos); + text << wxString::Format(wxT("%010d:"), data->m_start + pos); pre_pos = pos; @@ -1274,7 +1317,11 @@ void OPJMarkerTree::OnSelChanged(wxTreeEvent& event) for (c = 0; c < BUNCH_LINESIZE; c++) { if (pre_pos < max_read) { - if ((buffer[pre_pos] == '\n') || (buffer[pre_pos] == '\t')) + if ((buffer[pre_pos] == '\n') || + (buffer[pre_pos] == '\t') || + (buffer[pre_pos] == '\0') || + (buffer[pre_pos] == 0x0D) || + (buffer[pre_pos] == 0x0B)) buffer[pre_pos] = ' '; text << wxString::Format(wxT("%c."), wxChar(buffer[pre_pos])); } else @@ -1410,7 +1457,7 @@ void OPJMarkerTree::OnSelChanged(wxTreeEvent& event) } } - wxLogMessage( wxT("%s event: %s (flags = %c%c%c%c)"), + wxLogMessage(wxT("%s event: %s (flags = %c%c%c%c)"), name, key.c_str(), event.ControlDown() ? wxT('C') : wxT('-'), @@ -1539,17 +1586,19 @@ void OPJMarkerTree::OnEndLabelEdit(wxTreeEvent& event) wxLogMessage(wxT("OnItemActivated")); }*/ -/*void OPJMarkerTree::OnItemMenu(wxTreeEvent& event) +void OPJMarkerTree::OnItemMenu(wxTreeEvent& event) { - wxTreeItemId itemId = event.GetItem(); + /*wxTreeItemId itemId = event.GetItem(); OPJMarkerData *item = itemId.IsOk() ? (OPJMarkerData *)GetItemData(itemId) : NULL; wxLogMessage(wxT("OnItemMenu for item \"%s\""), item ? item->GetDesc() - : _T("")); + : _T(""));*/ - event.Skip(); -}*/ + //wxLogMessage(wxT("EEEEEEEEEE")); + + //event.Skip(); +} /*void OPJMarkerTree::OnContextMenu(wxContextMenuEvent& event) { @@ -1719,45 +1768,74 @@ void *OPJDecoThread::Entry() srand(GetId()); int m_countnum = rand() % 9; - text.Printf(wxT("Deco thread 0x%lx started (priority = %u, time = %d)."), - GetId(), GetPriority(), m_countnum); + //text.Printf(wxT("Deco thread 0x%lx started (priority = %u, time = %d)."), + // GetId(), GetPriority(), m_countnum); + text.Printf(wxT("Deco thread %d started"), m_canvas->m_childframe->m_winnumber); WriteText(text); - // wxLogMessage(text); -- test wxLog thread safeness - //wxBusyCursor wait; - //wxBusyInfo wait(wxT("Decoding image ...")); - - - /*for (m_count = 0; m_count < m_countnum; m_count++) { - // check if we were asked to exit - if ( TestDestroy() ) - break; - - text.Printf(wxT("[%u] Deco thread 0x%lx here."), m_count, GetId()); - WriteText(text); - - // wxSleep() can't be called from non-GUI thread! - wxThread::Sleep(10); - }*/ - - wxBitmap bitmap( 100, 100 ); + wxBitmap bitmap(100, 100); wxImage image = bitmap.ConvertToImage(); image.Destroy(); WriteText(m_canvas->m_fname.GetFullPath()); + // set handler properties + wxJ2KHandler *j2kkkhandler = (wxJ2KHandler *) wxImage::FindHandler( wxBITMAP_TYPE_J2K); + j2kkkhandler->m_reducefactor = wxGetApp().m_reducefactor; + j2kkkhandler->m_qualitylayers = wxGetApp().m_qualitylayers; + j2kkkhandler->m_components = wxGetApp().m_components; +#ifdef USE_JPWL + j2kkkhandler->m_enablejpwl = wxGetApp().m_enablejpwl; + j2kkkhandler->m_expcomps = wxGetApp().m_expcomps; + j2kkkhandler->m_maxtiles = wxGetApp().m_maxtiles; +#endif // USE_JPWL + + wxJP2Handler *jp222handler = (wxJP2Handler *) wxImage::FindHandler( wxBITMAP_TYPE_JP2); + jp222handler->m_reducefactor = wxGetApp().m_reducefactor; + jp222handler->m_qualitylayers = wxGetApp().m_qualitylayers; + jp222handler->m_components = wxGetApp().m_components; +#ifdef USE_JPWL + jp222handler->m_enablejpwl = wxGetApp().m_enablejpwl; + jp222handler->m_expcomps = wxGetApp().m_expcomps; + jp222handler->m_maxtiles = wxGetApp().m_maxtiles; +#endif // USE_JPWL + + wxMJ2Handler *mj222handler = (wxMJ2Handler *) wxImage::FindHandler( wxBITMAP_TYPE_MJ2); + mj222handler->m_reducefactor = wxGetApp().m_reducefactor; + mj222handler->m_qualitylayers = wxGetApp().m_qualitylayers; + mj222handler->m_components = wxGetApp().m_components; +#ifdef USE_JPWL + mj222handler->m_enablejpwl = wxGetApp().m_enablejpwl; + mj222handler->m_expcomps = wxGetApp().m_expcomps; + mj222handler->m_maxtiles = wxGetApp().m_maxtiles; +#endif // USE_JPWL + + // load the file if (!image.LoadFile(m_canvas->m_fname.GetFullPath(), wxBITMAP_TYPE_ANY), 0) { - wxLogError(wxT("Can't load image")); + WriteText(wxT("Can't load image")); return NULL; } - m_canvas->m_image = wxBitmap(image); - m_canvas->Refresh(); - m_canvas->SetScrollbars(20, 20, (int)(0.5 + (double) image.GetWidth() / 20.0), (int)(0.5 + (double) image.GetHeight() / 20.0)); + // assign 100% image + m_canvas->m_image100 = wxBitmap(image); - text.Printf(wxT("Deco thread 0x%lx finished."), GetId()); + // find a fit-to-width zoom + int zooml, wzooml, hzooml; + wxSize clientsize = m_canvas->GetClientSize(); + wzooml = (int) floor(100.0 * (double) clientsize.GetWidth() / (double) (2 * OPJ_CANVAS_BORDER + image.GetWidth())); + hzooml = (int) floor(100.0 * (double) clientsize.GetHeight() / (double) (2 * OPJ_CANVAS_BORDER + image.GetHeight())); + zooml = wxMin(100, wxMin(wzooml, hzooml)); + + // fit to width + m_canvas->m_childframe->m_frame->Rescale(zooml, m_canvas->m_childframe); + + //m_canvas->m_image = m_canvas->m_image100; + //m_canvas->Refresh(); + //m_canvas->SetScrollbars(20, 20, (int)(0.5 + (double) image.GetWidth() / 20.0), (int)(0.5 + (double) image.GetHeight() / 20.0)); + + //text.Printf(wxT("Deco thread 0x%lx finished."), GetId()); + text.Printf(wxT("Deco thread %d finished"), m_canvas->m_childframe->m_winnumber); WriteText(text); - // wxLogMessage(text); -- test wxLog thread safeness return NULL; } @@ -1796,14 +1874,11 @@ void OPJParseThread::OnExit() wxArrayThread& threads = wxGetApp().m_parse_threads; threads.Remove(this); - if ( threads.IsEmpty() ) - { + if (threads.IsEmpty()) { // signal the main thread that there are no more threads left if it is // waiting for us - if ( wxGetApp().m_parse_waitingUntilAllDone ) - { + if (wxGetApp().m_parse_waitingUntilAllDone) { wxGetApp().m_parse_waitingUntilAllDone = false; - wxGetApp().m_parse_semAllDone.Post(); } } @@ -1814,10 +1889,10 @@ void *OPJParseThread::Entry() wxString text; - srand( GetId() ); + srand(GetId()); int m_countnum = rand() % 9; text.Printf(wxT("Parse thread 0x%lx started (priority = %u, time = %d)."), - GetId(), GetPriority(), m_countnum); + GetId(), GetPriority(), m_countnum); WriteText(text); // wxLogMessage(text); -- test wxLog thread safeness @@ -1847,3 +1922,382 @@ void *OPJParseThread::Entry() return NULL; } + + + + + + + +// ---------------------------------------------------------------------------- +// OPJDecoderDialog +// ---------------------------------------------------------------------------- + +IMPLEMENT_CLASS(OPJDecoderDialog, wxPropertySheetDialog) + +BEGIN_EVENT_TABLE(OPJDecoderDialog, wxPropertySheetDialog) +#ifdef USE_JPWL + EVT_CHECKBOX(OPJDECO_ENABLEJPWL, OPJDecoderDialog::OnEnableJPWL) +#endif // USE_JPWL +END_EVENT_TABLE() + +OPJDecoderDialog::OPJDecoderDialog(wxWindow* win, int dialogType) +{ + SetExtraStyle(wxDIALOG_EX_CONTEXTHELP|wxWS_EX_VALIDATE_RECURSIVELY); + + int tabImage1 = -1; + int tabImage2 = -1; + + int resizeBorder = wxRESIZE_BORDER; + + m_imageList = NULL; + + Create(win, wxID_ANY, wxT("Decoder settings"), wxDefaultPosition, wxDefaultSize, + wxDEFAULT_DIALOG_STYLE| (int) wxPlatform::IfNot(wxOS_WINDOWS_CE, resizeBorder) + ); + + CreateButtons(wxOK | wxCANCEL | (int)wxPlatform::IfNot(wxOS_WINDOWS_CE, wxHELP)); + + wxBookCtrlBase* notebook = GetBookCtrl(); + notebook->SetImageList(m_imageList); + + wxPanel* mainSettings = CreateMainSettingsPage(notebook); +#ifdef USE_JPWL + wxPanel* jpwlSettings = CreateJPWLSettingsPage(notebook); +#endif // USE_JPWL + + notebook->AddPage(mainSettings, wxT("Main"), false); +#ifdef USE_JPWL + notebook->AddPage(jpwlSettings, wxT("JPWL"), false); +#endif // USE_JPWL + + LayoutDialog(); +} + +OPJDecoderDialog::~OPJDecoderDialog() +{ + delete m_imageList; +} + +/*wxPanel* OPJDecoderDialog::CreateGeneralSettingsPage(wxWindow* parent) +{ + wxPanel* panel = new wxPanel(parent, wxID_ANY); + + wxBoxSizer *topSizer = new wxBoxSizer( wxVERTICAL ); + wxBoxSizer *item0 = new wxBoxSizer( wxVERTICAL ); + + //// LOAD LAST FILE + + wxBoxSizer* itemSizer3 = new wxBoxSizer( wxHORIZONTAL ); + wxCheckBox* checkBox3 = new wxCheckBox(panel, ID_LOAD_LAST_PROJECT, _("&Load last project on startup"), wxDefaultPosition, wxDefaultSize); + itemSizer3->Add(checkBox3, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); + item0->Add(itemSizer3, 0, wxGROW|wxALL, 0); + + //// AUTOSAVE + + wxString autoSaveLabel = _("&Auto-save every"); + wxString minsLabel = _("mins"); + + wxBoxSizer* itemSizer12 = new wxBoxSizer( wxHORIZONTAL ); + wxCheckBox* checkBox12 = new wxCheckBox(panel, ID_AUTO_SAVE, autoSaveLabel, wxDefaultPosition, wxDefaultSize); + + wxSpinCtrl* spinCtrl12 = new wxSpinCtrl(panel, ID_AUTO_SAVE_MINS, wxEmptyString, + wxDefaultPosition, wxSize(40, wxDefaultCoord), wxSP_ARROW_KEYS, 1, 60, 1); + + itemSizer12->Add(checkBox12, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); + itemSizer12->Add(spinCtrl12, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); + itemSizer12->Add(new wxStaticText(panel, wxID_STATIC, minsLabel), 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); + item0->Add(itemSizer12, 0, wxGROW|wxALL, 0); + + //// TOOLTIPS + + wxBoxSizer* itemSizer8 = new wxBoxSizer( wxHORIZONTAL ); + wxCheckBox* checkBox6 = new wxCheckBox(panel, ID_SHOW_TOOLTIPS, _("Show &tooltips"), wxDefaultPosition, wxDefaultSize); + itemSizer8->Add(checkBox6, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); + item0->Add(itemSizer8, 0, wxGROW|wxALL, 0); + + topSizer->Add( item0, 1, wxGROW|wxALIGN_CENTRE|wxALL, 5 ); + + panel->SetSizer(topSizer); + topSizer->Fit(panel); + + return panel; +}*/ + +/*wxPanel* OPJDecoderDialog::CreateAestheticSettingsPage(wxWindow* parent) +{ + wxPanel* panel = new wxPanel(parent, wxID_ANY); + + wxBoxSizer *topSizer = new wxBoxSizer( wxVERTICAL ); + wxBoxSizer *item0 = new wxBoxSizer( wxVERTICAL ); + + //// PROJECT OR GLOBAL + wxString globalOrProjectChoices[2]; + globalOrProjectChoices[0] = _("&New projects"); + globalOrProjectChoices[1] = _("&This project"); + + wxRadioBox* projectOrGlobal = new wxRadioBox(panel, ID_APPLY_SETTINGS_TO, _("&Apply settings to:"), + wxDefaultPosition, wxDefaultSize, 2, globalOrProjectChoices); + item0->Add(projectOrGlobal, 0, wxGROW|wxALL, 5); + + projectOrGlobal->SetSelection(0); + + //// BACKGROUND STYLE + wxArrayString backgroundStyleChoices; + backgroundStyleChoices.Add(wxT("Colour")); + backgroundStyleChoices.Add(wxT("Image")); + wxStaticBox* staticBox3 = new wxStaticBox(panel, wxID_ANY, _("Background style:")); + + wxBoxSizer* styleSizer = new wxStaticBoxSizer( staticBox3, wxVERTICAL ); + item0->Add(styleSizer, 0, wxGROW|wxALL, 5); + + wxBoxSizer* itemSizer2 = new wxBoxSizer( wxHORIZONTAL ); + + wxChoice* choice2 = new wxChoice(panel, ID_BACKGROUND_STYLE, wxDefaultPosition, wxDefaultSize, backgroundStyleChoices); + + itemSizer2->Add(new wxStaticText(panel, wxID_ANY, _("&Window:")), 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); + itemSizer2->Add(5, 5, 1, wxALL, 0); + itemSizer2->Add(choice2, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); + + styleSizer->Add(itemSizer2, 0, wxGROW|wxALL, 5); + +#if wxUSE_SPINCTRL + //// FONT SIZE SELECTION + + wxStaticBox* staticBox1 = new wxStaticBox(panel, wxID_ANY, _("Tile font size:")); + wxBoxSizer* itemSizer5 = new wxStaticBoxSizer( staticBox1, wxHORIZONTAL ); + + wxSpinCtrl* spinCtrl = new wxSpinCtrl(panel, ID_FONT_SIZE, wxEmptyString, wxDefaultPosition, + wxSize(80, wxDefaultCoord)); + itemSizer5->Add(spinCtrl, 0, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + + item0->Add(itemSizer5, 0, wxGROW|wxLEFT|wxRIGHT, 5); +#endif + + topSizer->Add( item0, 1, wxGROW|wxALIGN_CENTRE|wxALL, 5 ); + topSizer->AddSpacer(5); + + panel->SetSizer(topSizer); + topSizer->Fit(panel); + + return panel; +}*/ + +wxPanel* OPJDecoderDialog::CreateMainSettingsPage(wxWindow* parent) +{ + wxPanel* panel = new wxPanel(parent, wxID_ANY); + + // top sizer + wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL); + + // add some space + //topSizer->AddSpacer(5); + + // sub top sizer + wxBoxSizer *subtopSizer = new wxBoxSizer(wxVERTICAL); + + // resolutions settings, column + wxStaticBox* resolutionBox = new wxStaticBox(panel, wxID_ANY, wxT("Resolutions")); + wxBoxSizer* resolutionSizer = new wxStaticBoxSizer(resolutionBox, wxVERTICAL); + + // reduce factor sizer, row + wxBoxSizer* reduceSizer = new wxBoxSizer(wxHORIZONTAL); + + // add some text + reduceSizer->Add(new wxStaticText(panel, wxID_ANY, wxT("&Reduce factor:")), + 0, wxALL | wxALIGN_CENTER_VERTICAL, 5); + + // add some horizontal space + reduceSizer->Add(5, 5, 1, wxALL, 0); + + // add the value control + reduceSizer->Add( + m_reduceCtrl = new wxSpinCtrl(panel, OPJDECO_REDUCEFACTOR, + wxString::Format(wxT("%d"), wxGetApp().m_reducefactor), + wxDefaultPosition, wxSize(80, wxDefaultCoord), + wxSP_ARROW_KEYS, + 0, 10000, wxGetApp().m_reducefactor), + 0, wxALL | wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL, 5); + + resolutionSizer->Add(reduceSizer, 0, wxGROW | wxALL, 5); + + subtopSizer->Add(resolutionSizer, 0, wxGROW | wxALL, 5); + + // quality layer settings, column + wxStaticBox* layerBox = new wxStaticBox(panel, wxID_ANY, wxT("Layers")); + wxBoxSizer* layerSizer = new wxStaticBoxSizer(layerBox, wxVERTICAL); + + // quality layers sizer, row + wxBoxSizer* qualitySizer = new wxBoxSizer(wxHORIZONTAL); + + // add some text + qualitySizer->Add(new wxStaticText(panel, wxID_ANY, wxT("&Quality layers:")), + 0, wxALL | wxALIGN_CENTER_VERTICAL, 5); + + // add some horizontal space + qualitySizer->Add(5, 5, 1, wxALL, 0); + + // add the value control + qualitySizer->Add( + m_layerCtrl = new wxSpinCtrl(panel, OPJDECO_QUALITYLAYERS, + wxString::Format(wxT("%d"), wxGetApp().m_qualitylayers), + wxDefaultPosition, wxSize(80, wxDefaultCoord), + wxSP_ARROW_KEYS, + 0, 100000, wxGetApp().m_qualitylayers), + 0, wxALL | wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL, 5); + + layerSizer->Add(qualitySizer, 0, wxGROW | wxALL, 5); + + subtopSizer->Add(layerSizer, 0, wxGROW | wxALL, 5); + + // component settings, column + wxStaticBox* compoBox = new wxStaticBox(panel, wxID_ANY, wxT("Components")); + wxBoxSizer* compoSizer = new wxStaticBoxSizer(compoBox, wxVERTICAL); + + // quality layers sizer, row + wxBoxSizer* numcompsSizer = new wxBoxSizer(wxHORIZONTAL); + + // add some text + numcompsSizer->Add(new wxStaticText(panel, wxID_ANY, wxT("&No. of components:")), + 0, wxALL | wxALIGN_CENTER_VERTICAL, 5); + + // add some horizontal space + numcompsSizer->Add(5, 5, 1, wxALL, 0); + + // add the value control + numcompsSizer->Add( + m_numcompsCtrl = new wxSpinCtrl(panel, OPJDECO_NUMCOMPS, + wxString::Format(wxT("%d"), wxGetApp().m_components), + wxDefaultPosition, wxSize(80, wxDefaultCoord), + wxSP_ARROW_KEYS, + 0, 100000, wxGetApp().m_components), + 0, wxALL | wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL, 5); + + compoSizer->Add(numcompsSizer, 0, wxGROW | wxALL, 5); + + subtopSizer->Add(compoSizer, 0, wxGROW | wxALL, 5); + + topSizer->Add(subtopSizer, 1, wxGROW | wxALIGN_CENTRE | wxALL, 5); + + // assign top and fit it + panel->SetSizer(topSizer); + topSizer->Fit(panel); + + return panel; +} + +#ifdef USE_JPWL +wxPanel* OPJDecoderDialog::CreateJPWLSettingsPage(wxWindow* parent) +{ + wxPanel* panel = new wxPanel(parent, wxID_ANY); + + // top sizer + wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL); + + // add some space + //topSizer->AddSpacer(5); + + // sub top sizer + wxBoxSizer *subtopSizer = new wxBoxSizer(wxVERTICAL); + + // add JPWL enabling check box + subtopSizer->Add( + m_enablejpwlCheck = new wxCheckBox(panel, OPJDECO_ENABLEJPWL, wxT("Enable JPWL"), wxDefaultPosition, wxDefaultSize), + 0, wxGROW | wxALL, 5); + m_enablejpwlCheck->SetValue(wxGetApp().m_enablejpwl); + + // component settings, column + wxStaticBox* compoBox = new wxStaticBox(panel, wxID_ANY, wxT("Components")); + wxBoxSizer* compoSizer = new wxStaticBoxSizer(compoBox, wxVERTICAL); + + // expected components sizer, row + wxBoxSizer* expcompsSizer = new wxBoxSizer(wxHORIZONTAL); + + // add some text + expcompsSizer->Add(new wxStaticText(panel, wxID_ANY, wxT("&Expected comps.:")), + 0, wxALL | wxALIGN_CENTER_VERTICAL, 5); + + // add some horizontal space + expcompsSizer->Add(5, 5, 1, wxALL, 0); + + // add the value control + expcompsSizer->Add( + m_expcompsCtrl = new wxSpinCtrl(panel, OPJDECO_EXPCOMPS, + wxString::Format(wxT("%d"), wxGetApp().m_expcomps), + wxDefaultPosition, wxSize(80, wxDefaultCoord), + wxSP_ARROW_KEYS, + 1, 100000, wxGetApp().m_expcomps), + 0, wxALL | wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL, 5); + m_expcompsCtrl->Enable(wxGetApp().m_enablejpwl); + + compoSizer->Add(expcompsSizer, 0, wxGROW | wxALL, 5); + + subtopSizer->Add(compoSizer, 0, wxGROW | wxALL, 5); + + // tiles settings, column + wxStaticBox* tileBox = new wxStaticBox(panel, wxID_ANY, wxT("Tiles")); + wxBoxSizer* tileSizer = new wxStaticBoxSizer(tileBox, wxVERTICAL); + + // maximum tiles sizer, row + wxBoxSizer* maxtileSizer = new wxBoxSizer(wxHORIZONTAL); + + // add some text + maxtileSizer->Add(new wxStaticText(panel, wxID_ANY, wxT("&Max. no. of tiles:")), + 0, wxALL | wxALIGN_CENTER_VERTICAL, 5); + + // add some horizontal space + maxtileSizer->Add(5, 5, 1, wxALL, 0); + + // add the value control + maxtileSizer->Add( + m_maxtilesCtrl = new wxSpinCtrl(panel, OPJDECO_MAXTILES, + wxString::Format(wxT("%d"), wxGetApp().m_maxtiles), + wxDefaultPosition, wxSize(80, wxDefaultCoord), + wxSP_ARROW_KEYS, + 1, 100000, wxGetApp().m_maxtiles), + 0, wxALL | wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL, 5); + m_maxtilesCtrl->Enable(wxGetApp().m_enablejpwl); + + tileSizer->Add(maxtileSizer, 0, wxGROW | wxALL, 5); + + subtopSizer->Add(tileSizer, 0, wxGROW | wxALL, 5); + + topSizer->Add(subtopSizer, 1, wxGROW | wxALIGN_CENTRE | wxALL, 5); + + // assign top and fit it + panel->SetSizer(topSizer); + topSizer->Fit(panel); + + return panel; +} + +void OPJDecoderDialog::OnEnableJPWL(wxCommandEvent& event) +{ + if (event.IsChecked()) { + wxLogMessage(wxT("JPWL enabled")); + m_expcompsCtrl->Enable(true); + m_maxtilesCtrl->Enable(true); + } else { + wxLogMessage(wxT("JPWL disabled")); + m_expcompsCtrl->Enable(false); + m_maxtilesCtrl->Enable(false); + } + +} + +bool OPJDnDFile::OnDropFiles(wxCoord, wxCoord, const wxArrayString& filenames) +{ + /*size_t nFiles = filenames.GetCount(); + wxString str; + str.Printf( _T("%d files dropped\n"), (int)nFiles); + for ( size_t n = 0; n < nFiles; n++ ) { + str << filenames[n] << wxT("\n"); + } + wxLogMessage(str);*/ + m_pOwner->OpenFiles(filenames, filenames); + + return true; +} + +#endif // USE_JPWL + diff --git a/OPJViewer/source/OPJViewer.h b/OPJViewer/source/OPJViewer.h index f386ea8c..7a7ea328 100644 --- a/OPJViewer/source/OPJViewer.h +++ b/OPJViewer/source/OPJViewer.h @@ -43,6 +43,16 @@ // Copyright: (c) Julian Smart // Licence: wxWindows license ///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// +// Name: dialogs.h +// Purpose: Common dialogs demo +// Author: Julian Smart +// Modified by: ABX (2004) - adjustementd for conditional building +// Created: 04/01/98 +// RCS-ID: $Id: dialogs.h,v 1.50 2006/10/08 14:12:59 VZ Exp $ +// Copyright: (c) Julian Smart +// Licence: wxWindows license +///////////////////////////////////////////////////////////////////////////// #ifndef __OPJ_VIEWER_H__ #define __OPJ_VIEWER_H__ @@ -76,6 +86,14 @@ #include #include #include "wx/notebook.h" +#include + +#include "wx/propdlg.h" +#include "wx/spinctrl.h" + +#include +#include "wx/wxhtml.h" +#include "wx/statline.h" #include "libopenjpeg\openjpeg.h" @@ -83,6 +101,14 @@ #include "imagjp2.h" #include "imagmj2.h" +#ifdef __WXMSW__ +typedef unsigned __int64 int8byte; +#endif // __WXMSW__ + +#ifdef __WXGTK__ +typedef unsigned long long int8byte; +#endif // __WXGTK__ + #define USE_GENERIC_TREECTRL 0 #if USE_GENERIC_TREECTRL @@ -94,7 +120,7 @@ #endif #define OPJ_APPLICATION_NAME wxT("OpenJPEG Viewer") -#define OPJ_APPLICATION_VERSION wxT("0.1 alpha") +#define OPJ_APPLICATION_VERSION wxT("0.2 alpha") #define OPJ_APPLICATION_TITLEBAR OPJ_APPLICATION_NAME wxT(" ") OPJ_APPLICATION_VERSION #define OPJ_APPLICATION_COPYRIGHT wxT("(C) 2007, Giuseppe Baruffa") @@ -140,6 +166,13 @@ class OPJViewerApp: public wxApp // the list of all filenames written in the command line wxArrayString m_filelist; + // decoding engine parameters + int m_reducefactor, m_qualitylayers, m_components; +#ifdef USE_JPWL + bool m_enablejpwl; + int m_expcomps, m_maxtiles; +#endif // USE_JPWL + // private methods and variables private: bool m_showImages, m_showButtons; @@ -163,9 +196,11 @@ class OPJCanvas: public wxScrolledWindow void OnEvent(wxMouseEvent& event); void WriteText(const wxString& text) { wxMutexGuiEnter(); wxLogMessage(text); wxMutexGuiLeave();} OPJDecoThread *CreateDecoThread(void); + OPJChildFrame *m_childframe; - wxBitmap m_image; + wxBitmap m_image, m_image100; wxFileName m_fname; + long m_zooml; DECLARE_EVENT_TABLE() }; @@ -223,7 +258,7 @@ public: void OnEndLabelEdit(wxTreeEvent& event);*/ /*void OnDeleteItem(wxTreeEvent& event);*/ /*void OnContextMenu(wxContextMenuEvent& event);*/ - /*void OnItemMenu(wxTreeEvent& event);*/ + void OnItemMenu(wxTreeEvent& event); /*void OnGetInfo(wxTreeEvent& event); void OnSetInfo(wxTreeEvent& event);*/ /*void OnItemExpanded(wxTreeEvent& event);*/ @@ -304,10 +339,15 @@ class OPJFrame: public wxMDIParentFrame void OnAbout(wxCommandEvent& WXUNUSED(event)); void OnFileOpen(wxCommandEvent& WXUNUSED(event)); void OnQuit(wxCommandEvent& WXUNUSED(event)); + void OnClose(wxCommandEvent& WXUNUSED(event)); + void OnZoom(wxCommandEvent& WXUNUSED(event)); + void OnFit(wxCommandEvent& WXUNUSED(event)); void OnToggleWindow(wxCommandEvent& WXUNUSED(event)); + void OnSetsDeco(wxCommandEvent& event); void OnSashDrag(wxSashEvent& event); void OpenFiles(wxArrayString paths, wxArrayString filenames); void OnNotebook(wxNotebookEvent& event); + void Rescale(int scale, OPJChildFrame *child); OPJMarkerTreeHash m_treehash; OPJChildFrameHash m_childhash; @@ -345,25 +385,29 @@ class OPJChildFrame: public wxMDIChildFrame /*void OnQuit(wxCommandEvent& WXUNUSED(event));*/ void OnClose(wxCloseEvent& event); void OnGotFocus(wxFocusEvent& event); - /*void OnLostFocus(wxFocusEvent& event);*/ + void OnLostFocus(wxFocusEvent& event); OPJFrame *m_frame; wxFileName m_fname; int m_winnumber; -DECLARE_EVENT_TABLE() + DECLARE_EVENT_TABLE() }; -#define SASHTEST_QUIT wxID_EXIT -#define SASHTEST_NEW_WINDOW 2 -#define SASHTEST_REFRESH 3 -#define SASHTEST_CHILD_QUIT 4 -#define SASHTEST_ABOUT wxID_ABOUT -#define SASHTEST_TOGGLE_WINDOW 6 +// frame and main menu ids +enum { + OPJFRAME_FILEEXIT = wxID_EXIT, + OPJFRAME_HELPABOUT = wxID_ABOUT, + OPJFRAME_FILEOPEN, + OPJFRAME_FILETOGGLE, + OPJFRAME_VIEWZOOM, + OPJFRAME_VIEWFIT, + OPJFRAME_FILECLOSE, + OPJFRAME_SETSDECO, + + OPJFRAME_BROWSEWIN = 10000, + OPJFRAME_LOGWIN +}; -#define ID_WINDOW_TOP 100 -#define ID_WINDOW_LEFT1 101 -#define ID_WINDOW_LEFT2 102 -#define ID_WINDOW_BOTTOM 103 // menu and control ids enum @@ -466,4 +510,56 @@ private: }; + +// Drag and drop files target +class OPJDnDFile: public wxFileDropTarget +{ +public: + OPJDnDFile(OPJFrame *pOwner) { m_pOwner = pOwner; } + virtual bool OnDropFiles(wxCoord x, wxCoord y, const wxArrayString& filenames); + +private: + OPJFrame *m_pOwner; +}; + + + +// Property sheet dialog +class OPJDecoderDialog: public wxPropertySheetDialog +{ +DECLARE_CLASS(OPJDecoderDialog) +public: + OPJDecoderDialog(wxWindow* parent, int dialogType); + ~OPJDecoderDialog(); + + wxSpinCtrl *m_reduceCtrl, *m_layerCtrl, *m_numcompsCtrl; + + wxPanel* CreateMainSettingsPage(wxWindow* parent); +#ifdef USE_JPWL + void OnEnableJPWL(wxCommandEvent& event); + wxPanel* CreateJPWLSettingsPage(wxWindow* parent); + wxSpinCtrl *m_expcompsCtrl, *m_maxtilesCtrl; + wxCheckBox *m_enablejpwlCheck; +#endif // USE_JPWL + + +protected: + + enum { + OPJDECO_REDUCEFACTOR = 100, + OPJDECO_QUALITYLAYERS, + OPJDECO_NUMCOMPS, + OPJDECO_ENABLEJPWL, + OPJDECO_EXPCOMPS, + OPJDECO_MAXTILES + }; + + wxImageList* m_imageList; + +DECLARE_EVENT_TABLE() +}; + #endif //__OPJ_VIEWER_H__ + + + diff --git a/OPJViewer/source/OPJViewer.rc b/OPJViewer/source/OPJViewer.rc index 56e5b698..fb5a5def 100644 --- a/OPJViewer/source/OPJViewer.rc +++ b/OPJViewer/source/OPJViewer.rc @@ -1,2 +1,3 @@ +OPJChild16 ICON OPJChild.ico OPJViewer16 ICON OPJViewer.ico #include "wx/msw/wx.rc" \ No newline at end of file diff --git a/OPJViewer/source/imagj2k.cpp b/OPJViewer/source/imagj2k.cpp index 16bcdd16..2442aa4e 100644 --- a/OPJViewer/source/imagj2k.cpp +++ b/OPJViewer/source/imagj2k.cpp @@ -51,10 +51,6 @@ #include "wx/module.h" #endif - -#include "libopenjpeg/openjpeg.h" - - #include "wx/filefn.h" #include "wx/wfstream.h" @@ -150,12 +146,18 @@ bool wxJ2KHandler::LoadFile(wxImage *image, wxInputStream& stream, bool verbose, strncpy(parameters.outfile, "", sizeof(parameters.outfile)-1); parameters.decod_format = J2K_CFMT; parameters.cod_format = BMP_DFMT; + if (m_reducefactor) + parameters.cp_reduce = m_reducefactor; + if (m_qualitylayers) + parameters.cp_layer = m_qualitylayers; + /*if (n_components) + parameters. = n_components;*/ /* JPWL only */ #ifdef USE_JPWL - parameters.jpwl_exp_comps = JPWL_EXPECTED_COMPONENTS; - parameters.jpwl_max_tiles = JPWL_MAXIMUM_TILES; - parameters.jpwl_correct = true; + parameters.jpwl_exp_comps = m_expcomps; + parameters.jpwl_max_tiles = m_maxtiles; + parameters.jpwl_correct = m_enablejpwl; #endif /* USE_JPWL */ /* get a decoder handle */ @@ -183,7 +185,7 @@ bool wxJ2KHandler::LoadFile(wxImage *image, wxInputStream& stream, bool verbose, opjimage = opj_decode(dinfo, cio); if (!opjimage) { wxMutexGuiEnter(); - wxLogError("J2K: failed to decode image!"); + wxLogError(wxT("J2K: failed to decode image!")); wxMutexGuiLeave(); opj_destroy_decompress(dinfo); opj_cio_close(cio); @@ -198,7 +200,7 @@ bool wxJ2KHandler::LoadFile(wxImage *image, wxInputStream& stream, bool verbose, // check image components if ((opjimage->numcomps != 1) && (opjimage->numcomps != 3)) { wxMutexGuiEnter(); - wxLogError("J2K: weird number of components"); + wxLogError(wxT("J2K: weird number of components")); wxMutexGuiLeave(); opj_destroy_decompress(dinfo); free(src); diff --git a/OPJViewer/source/imagj2k.h b/OPJViewer/source/imagj2k.h index c98fdd2e..b262ec6b 100644 --- a/OPJViewer/source/imagj2k.h +++ b/OPJViewer/source/imagj2k.h @@ -44,9 +44,19 @@ #if wxUSE_LIBOPENJPEG #include "wx/image.h" +#include "libopenjpeg/openjpeg.h" #define wxBITMAP_TYPE_J2K 47 +#define wxIMAGE_OPTION_REDUCEFACTOR wxString(_T("reducefactor")) +#define wxIMAGE_OPTION_QUALITYLAYERS wxString(_T("qualitylayers")) +#define wxIMAGE_OPTION_MAXCOMPS wxString(_T("maxcomps")) +#ifdef USE_JPWL +#define wxIMAGE_OPTION_ENABLEJPWL wxString(_T("enablejpwl")) +#define wxIMAGE_OPTION_EXPCOMPS wxString(_T("expcomps")) +#define wxIMAGE_OPTION_MAXTILES wxString(_T("maxtiles")) +#endif // USE_JPWL + class WXDLLEXPORT wxJ2KHandler: public wxImageHandler { public: @@ -56,8 +66,24 @@ public: m_extension = wxT("j2k"); m_type = wxBITMAP_TYPE_J2K; m_mime = wxT("image/j2k"); + + m_reducefactor = 0; + m_qualitylayers = 0; + m_components = 0; +#ifdef USE_JPWL + m_enablejpwl = true; + m_expcomps = JPWL_EXPECTED_COMPONENTS; + m_maxtiles = JPWL_MAXIMUM_TILES; +#endif // USE_JPWL } + // decoding engine parameters + int m_reducefactor, m_qualitylayers, m_components; +#ifdef USE_JPWL + bool m_enablejpwl; + int m_expcomps, m_maxtiles; +#endif // USE_JPWL + #if wxUSE_STREAMS virtual bool LoadFile( wxImage *image, wxInputStream& stream, bool verbose=true, int index=-1 ); virtual bool SaveFile( wxImage *image, wxOutputStream& stream, bool verbose=true ); diff --git a/OPJViewer/source/imagjp2.cpp b/OPJViewer/source/imagjp2.cpp index 99ef23c9..ce25bb1e 100644 --- a/OPJViewer/source/imagjp2.cpp +++ b/OPJViewer/source/imagjp2.cpp @@ -149,6 +149,19 @@ bool wxJP2Handler::LoadFile(wxImage *image, wxInputStream& stream, bool verbose, strncpy(parameters.outfile, "", sizeof(parameters.outfile)-1); parameters.decod_format = JP2_CFMT; parameters.cod_format = BMP_DFMT; + if (m_reducefactor) + parameters.cp_reduce = m_reducefactor; + if (m_qualitylayers) + parameters.cp_layer = m_qualitylayers; + /*if (n_components) + parameters. = n_components;*/ + + /* JPWL only */ +#ifdef USE_JPWL + parameters.jpwl_exp_comps = m_expcomps; + parameters.jpwl_max_tiles = m_maxtiles; + parameters.jpwl_correct = m_enablejpwl; +#endif /* USE_JPWL */ /* get a decoder handle */ dinfo = opj_create_decompress(CODEC_JP2); @@ -175,7 +188,7 @@ bool wxJP2Handler::LoadFile(wxImage *image, wxInputStream& stream, bool verbose, opjimage = opj_decode(dinfo, cio); if (!opjimage) { wxMutexGuiEnter(); - wxLogError("JP2: failed to decode image!"); + wxLogError(wxT("JP2: failed to decode image!")); wxMutexGuiLeave(); opj_destroy_decompress(dinfo); opj_cio_close(cio); @@ -189,7 +202,7 @@ bool wxJP2Handler::LoadFile(wxImage *image, wxInputStream& stream, bool verbose, // check image size if ((opjimage->numcomps != 1) && (opjimage->numcomps != 3)) { wxMutexGuiEnter(); - wxLogError("JP2: weird number of components"); + wxLogError(wxT("JP2: weird number of components")); wxMutexGuiLeave(); opj_destroy_decompress(dinfo); free(src); diff --git a/OPJViewer/source/imagjp2.h b/OPJViewer/source/imagjp2.h index 1ebad878..b30f111a 100644 --- a/OPJViewer/source/imagjp2.h +++ b/OPJViewer/source/imagjp2.h @@ -44,6 +44,7 @@ #if wxUSE_LIBOPENJPEG #include "wx/image.h" +#include "libopenjpeg/openjpeg.h" #define wxBITMAP_TYPE_JP2 48 @@ -56,8 +57,24 @@ public: m_extension = wxT("jp2"); m_type = wxBITMAP_TYPE_JP2; m_mime = wxT("image/jp2"); + + m_reducefactor = 0; + m_qualitylayers = 0; + m_components = 0; +#ifdef USE_JPWL + m_enablejpwl = true; + m_expcomps = JPWL_EXPECTED_COMPONENTS; + m_maxtiles = JPWL_MAXIMUM_TILES; +#endif // USE_JPWL } + // decoding engine parameters + int m_reducefactor, m_qualitylayers, m_components; +#ifdef USE_JPWL + bool m_enablejpwl; + int m_expcomps, m_maxtiles; +#endif // USE_JPWL + #if wxUSE_STREAMS virtual bool LoadFile( wxImage *image, wxInputStream& stream, bool verbose=true, int index=-1 ); virtual bool SaveFile( wxImage *image, wxOutputStream& stream, bool verbose=true ); diff --git a/OPJViewer/source/imagmj2.cpp b/OPJViewer/source/imagmj2.cpp index 65c9ca73..2a4d2e58 100644 --- a/OPJViewer/source/imagmj2.cpp +++ b/OPJViewer/source/imagmj2.cpp @@ -199,6 +199,7 @@ typedef enum { #define TKHD_SIGN "tkhd" #define MDIA_SIGN "mdia" #define MINF_SIGN "minf" +#define VMHD_SIGN "vmhd" #define STBL_SIGN "stbl" #define STSD_SIGN "stsd" #define MJP2_SIGN "mjp2" @@ -503,14 +504,14 @@ searchfirstjp2c(wxInputStream& stream, unsigned long int fsize) char scansign[] = "jp2c"; unsigned long int scanpoint = 0L; - wxLogMessage("MJ2: searching jp2c box... "); + wxLogMessage(wxT("MJ2: searching jp2c box... ")); /* do the parsing */ if (my_jpeg2000parse(stream, 0, fsize, 0, scansign, &scanpoint) < 0) - wxLogMessage("MJ2: Unrecoverable error during file parsing: stopping"); + wxLogMessage(wxT("MJ2: Unrecoverable error during file parsing: stopping")); if (strcmp(scansign, " ")) - wxLogMessage("MJ2: not found"); + wxLogMessage(wxT("MJ2: not found")); else { wxLogMessage(wxString::Format("MJ2: found at byte %d", scanpoint)); @@ -528,16 +529,16 @@ searchjpegheaderbox(wxInputStream& stream, unsigned long int fsize) char scansign[] = "jp2h"; unsigned long int scanpoint = 0L; - wxLogMessage("MJ2: searching jp2h box... "); + wxLogMessage(wxT("MJ2: searching jp2h box... ")); /* do the parsing */ if (my_jpeg2000parse(stream, 0, fsize, 0, scansign, &scanpoint) < 0) - wxLogMessage("Unrecoverable error during file parsing: stopping"); + wxLogMessage(wxT("Unrecoverable error during file parsing: stopping")); if (strcmp(scansign, " ")) - wxLogMessage("MJ2: not found"); + wxLogMessage(wxT("MJ2: not found")); else - wxLogMessage(wxString::Format("MJ2: found at byte %d", scanpoint)); + wxLogMessage(wxString::Format(wxT("MJ2: found at byte %d"), scanpoint)); return (scanpoint); } @@ -615,6 +616,19 @@ bool wxMJ2Handler::LoadFile(wxImage *image, wxInputStream& stream, bool verbose, strncpy(parameters.outfile, "", sizeof(parameters.outfile)-1); parameters.decod_format = JP2_CFMT; parameters.cod_format = BMP_DFMT; + if (m_reducefactor) + parameters.cp_reduce = m_reducefactor; + if (m_qualitylayers) + parameters.cp_layer = m_qualitylayers; + /*if (n_components) + parameters. = n_components;*/ + + /* JPWL only */ +#ifdef USE_JPWL + parameters.jpwl_exp_comps = m_expcomps; + parameters.jpwl_max_tiles = m_maxtiles; + parameters.jpwl_correct = m_enablejpwl; +#endif /* USE_JPWL */ /* get a decoder handle */ dinfo = opj_create_decompress(CODEC_JP2); @@ -664,7 +678,7 @@ bool wxMJ2Handler::LoadFile(wxImage *image, wxInputStream& stream, bool verbose, opjimage = opj_decode(dinfo, cio); if (!opjimage) { wxMutexGuiEnter(); - wxLogError("MJ2: failed to decode image!"); + wxLogError(wxT("MJ2: failed to decode image!")); wxMutexGuiLeave(); opj_destroy_decompress(dinfo); opj_cio_close(cio); @@ -678,7 +692,7 @@ bool wxMJ2Handler::LoadFile(wxImage *image, wxInputStream& stream, bool verbose, // check image size if ((opjimage->numcomps != 1) && (opjimage->numcomps != 3)) { wxMutexGuiEnter(); - wxLogError("MJ2: weird number of components"); + wxLogError(wxT("MJ2: weird number of components")); wxMutexGuiLeave(); opj_destroy_decompress(dinfo); free(src); diff --git a/OPJViewer/source/imagmj2.h b/OPJViewer/source/imagmj2.h index 1c9667f8..e1737275 100644 --- a/OPJViewer/source/imagmj2.h +++ b/OPJViewer/source/imagmj2.h @@ -44,6 +44,7 @@ #if wxUSE_LIBOPENJPEG #include "wx/image.h" +#include "libopenjpeg/openjpeg.h" #define wxBITMAP_TYPE_MJ2 49 @@ -56,8 +57,24 @@ public: m_extension = wxT("mj2"); m_type = wxBITMAP_TYPE_MJ2; m_mime = wxT("image/mj2"); + + m_reducefactor = 0; + m_qualitylayers = 0; + m_components = 0; +#ifdef USE_JPWL + m_enablejpwl = true; + m_expcomps = JPWL_EXPECTED_COMPONENTS; + m_maxtiles = JPWL_MAXIMUM_TILES; +#endif // USE_JPWL } + // decoding engine parameters + int m_reducefactor, m_qualitylayers, m_components; +#ifdef USE_JPWL + bool m_enablejpwl; + int m_expcomps, m_maxtiles; +#endif // USE_JPWL + #if wxUSE_STREAMS virtual bool LoadFile( wxImage *image, wxInputStream& stream, bool verbose=true, int index=-1 ); virtual bool SaveFile( wxImage *image, wxOutputStream& stream, bool verbose=true ); diff --git a/OPJViewer/source/license.txt b/OPJViewer/source/license.txt new file mode 100644 index 00000000..2d0f584a --- /dev/null +++ b/OPJViewer/source/license.txt @@ -0,0 +1,13 @@ +Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium +Copyright (c) 2002-2007, Professor Benoit Macq +Copyright (c) 2001-2003, David Janssens +Copyright (c) 2002-2003, Yannick Verschueren +Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe +Copyright (c) 2005, Herve Drolon, FreeImage Team +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditionsare met: +1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/OPJViewer/source/readmeafter.txt b/OPJViewer/source/readmeafter.txt new file mode 100644 index 00000000..deffff3f --- /dev/null +++ b/OPJViewer/source/readmeafter.txt @@ -0,0 +1 @@ +Good choice! \ No newline at end of file diff --git a/OPJViewer/source/readmebefore.txt b/OPJViewer/source/readmebefore.txt new file mode 100644 index 00000000..c5e1ed87 --- /dev/null +++ b/OPJViewer/source/readmebefore.txt @@ -0,0 +1,11 @@ +What is OpenJPEG ? +================== +The OpenJPEG library is an open-source JPEG 2000 codec written in C language. It has been developed in order to promote the use of JPEG 2000, the new still-image compression standard from the Joint Photographic Experts Group (JPEG). In addition to the basic codec, various other features are under development, among them the JP2 and MJ2 (Motion JPEG 2000) file formats, an indexing tool useful for the JPIP protocol, JPWL-tools for error-resilience, a Java-viewer for j2k-images, ... + +Who can use the library ? +========================= +Anybody. As the OpenJPEG library is released under the BSD license, anybody can use or modify the library, even for commercial applications. The only restriction is to retain the copyright in the sources or the binaries documentation. + +Who is developing the library ? +=============================== +The library is developed by the Communications and Remote Sensing Lab (TELE), in the Université Catholique de Louvain (UCL). The JPWL module is developped and maintained by the Digital Signal Processing Lab (DSPLab) of the University of Perugia, Italy (UNIPG). As our purpose is to make OpenJPEG really useful for those interested in the image compression field, any feedback/advices are obviously welcome ! We will do our best to handle them quickly. \ No newline at end of file diff --git a/OPJViewer/source/wxj2kparser.cpp b/OPJViewer/source/wxj2kparser.cpp index 7e189d7b..30289567 100644 --- a/OPJViewer/source/wxj2kparser.cpp +++ b/OPJViewer/source/wxj2kparser.cpp @@ -196,7 +196,7 @@ void OPJParseThread::ParseJ2KFile(wxFile *m_file, wxFileOffset offset, wxFileOff // marker name wxTreeItemId subcurrid1 = m_tree->AppendItem(currid, - wxT("*** ") + wxString(marker_descr[m]) + wxT(" ***"), + wxT("*** ") + wxString::Format(wxT("%s"), marker_descr[m]) + wxT(" ***"), image, imageSel, new OPJMarkerData(wxT("INFO")) ); diff --git a/OPJViewer/source/wxjp2parser.cpp b/OPJViewer/source/wxjp2parser.cpp index 7d8f3447..c929418d 100644 --- a/OPJViewer/source/wxjp2parser.cpp +++ b/OPJViewer/source/wxjp2parser.cpp @@ -61,8 +61,10 @@ typedef enum { TKHD_BOX, MDIA_BOX, MINF_BOX, + VMHD_BOX, STBL_BOX, STSD_BOX, + STSZ_BOX, MJP2_BOX, MDAT_BOX, ANY_BOX, @@ -377,15 +379,15 @@ int OPJParseThread::box_handler_function(int boxtype, wxFile *fileid, wxFileOffs new OPJMarkerData(wxT("INFO")) ); } else { - unsigned __int64 creation_time, modification_time, duration; + int8byte creation_time, modification_time, duration; unsigned long int timescale; - fileid->Read(&creation_time, sizeof(unsigned __int64)); + fileid->Read(&creation_time, sizeof(int8byte)); creation_time = BYTE_SWAP8(creation_time); - fileid->Read(&modification_time, sizeof(unsigned __int64)); + fileid->Read(&modification_time, sizeof(int8byte)); modification_time = BYTE_SWAP8(modification_time); fileid->Read(×cale, sizeof(unsigned long int)); timescale = BYTE_SWAP4(timescale); - fileid->Read(&duration, sizeof(unsigned __int64)); + fileid->Read(&duration, sizeof(int8byte)); duration = BYTE_SWAP8(duration); wxTreeItemId currid = m_tree->AppendItem(parentid, wxString::Format(wxT("Creation time: %u"), creation_time), @@ -454,6 +456,110 @@ int OPJParseThread::box_handler_function(int boxtype, wxFile *fileid, wxFileOffs break; + /* Sample Size box */ + case (STSZ_BOX): { + + unsigned long int version, sample_size, sample_count, entry_size; + + fileid->Read(&version, sizeof(unsigned long int)); + version = BYTE_SWAP4(version); + + fileid->Read(&sample_size, sizeof(unsigned long int)); + sample_size = BYTE_SWAP4(sample_size); + + if (sample_size == 0) { + fileid->Read(&sample_count, sizeof(unsigned long int)); + sample_count = BYTE_SWAP4(sample_count); + + wxTreeItemId currid = m_tree->AppendItem(parentid, + wxString::Format(wxT("Sample count: %d"), sample_count), + m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1, + new OPJMarkerData(wxT("INFO"), m_tree->m_fname.GetFullPath(), filepoint, filelimit) + ); + + currid = m_tree->AppendItem(parentid, + wxT("Entries size (bytes)"), + m_tree->TreeCtrlIcon_Folder, m_tree->TreeCtrlIcon_Folder + 1, + new OPJMarkerData(wxT("INFO"), m_tree->m_fname.GetFullPath(), filepoint, filelimit) + ); + + wxString text; + for (int s = 0; s < sample_count; s++) { + fileid->Read(&entry_size, sizeof(unsigned long int)); + entry_size = BYTE_SWAP4(entry_size); + + text << wxString::Format(wxT("%d, "), entry_size); + + if (((s % 10) == (ITEM_PER_ROW - 1)) || (s == (sample_count - 1))) { + m_tree->AppendItem(currid, + text, + m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1, + new OPJMarkerData(wxT("INFO"), m_tree->m_fname.GetFullPath(), filepoint, filelimit) + ); + text = wxT(""); + } + + } + + } + + }; + break; + + + /* Video Media Header box */ + case (VMHD_BOX): { + + unsigned long int version; + unsigned short int graphicsmode, opcolor[3]; + char graphicsdescr[100]; + + fileid->Read(&version, sizeof(unsigned long int)); + version = BYTE_SWAP4(version); + + fileid->Read(&graphicsmode, sizeof(unsigned short int)); + graphicsmode = BYTE_SWAP2(graphicsmode); + switch (graphicsmode) { + case (0x00): + strcpy(graphicsdescr, "copy"); + break; + case (0x24): + strcpy(graphicsdescr, "transparent"); + break; + case (0x0100): + strcpy(graphicsdescr, "alpha"); + break; + case (0x0101): + strcpy(graphicsdescr, "whitealpha"); + break; + case (0x0102): + strcpy(graphicsdescr, "blackalpha"); + break; + default: + strcpy(graphicsdescr, "unknown"); + break; + }; + + fileid->Read(opcolor, 3 * sizeof(unsigned short int)); + opcolor[0] = BYTE_SWAP2(opcolor[0]); + opcolor[1] = BYTE_SWAP2(opcolor[1]); + opcolor[2] = BYTE_SWAP2(opcolor[2]); + + wxTreeItemId currid = m_tree->AppendItem(parentid, + wxString::Format(wxT("Composition mode: %d (%s)"), graphicsmode, graphicsdescr), + m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1, + new OPJMarkerData(wxT("INFO"), m_tree->m_fname.GetFullPath(), filepoint, filelimit) + ); + + currid = m_tree->AppendItem(parentid, + wxString::Format(wxT("OP color: %d %d %d"), opcolor[0], opcolor[1], opcolor[2]), + m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1, + new OPJMarkerData(wxT("INFO"), m_tree->m_fname.GetFullPath(), filepoint, filelimit) + ); + }; + break; + + /* MJP2 Sample Description box */ case (MJP2_BOX): { @@ -500,8 +606,6 @@ int OPJParseThread::box_handler_function(int boxtype, wxFile *fileid, wxFileOffs default: break; - - }; return (0); @@ -525,8 +629,10 @@ int OPJParseThread::box_handler_function(int boxtype, wxFile *fileid, wxFileOffs #define TKHD_SIGN "tkhd" #define MDIA_SIGN "mdia" #define MINF_SIGN "minf" +#define VMHD_SIGN "vmhd" #define STBL_SIGN "stbl" #define STSD_SIGN "stsd" +#define STSZ_SIGN "stsz" #define MJP2_SIGN "mjp2" #define MDAT_SIGN "mdat" #define ANY_SIGN "" @@ -658,6 +764,13 @@ struct boxdef j2box[] = /* req */ {1, 1, 1}, /* ins */ MDIA_BOX}, +/* sign */ {VMHD_SIGN, +/* short */ "Video Media Header box", +/* long */ "The video media header contains general presentation information, independent of the coding, for video media", +/* sbox */ 0, +/* req */ {1, 1, 1}, +/* ins */ MINF_BOX}, + /* sign */ {STBL_SIGN, /* short */ "Sample Table box", /* long */ "The sample table contains all the time and data indexing of the media samples in a track", @@ -666,13 +779,20 @@ struct boxdef j2box[] = /* ins */ MINF_BOX}, /* sign */ {STSD_SIGN, -/* short */ "Sample Description box", +/* short */ "STSD Sample Description box", /* long */ "The sample description table gives detailed information about the coding type used, and any initialization " "information needed for that coding", /* sbox */ 0, /* req */ {1, 1, 1}, /* ins */ MINF_BOX}, +/* sign */ {STSZ_SIGN, +/* short */ "Sample Size box", +/* long */ "This box contains the sample count and a table giving the size of each sample", +/* sbox */ 0, +/* req */ {1, 1, 1}, +/* ins */ STBL_BOX}, + /* sign */ {MJP2_SIGN, /* short */ "MJP2 Sample Description box", /* long */ "The MJP2 sample description table gives detailed information about the coding type used, and any initialization " @@ -727,7 +847,7 @@ int OPJParseThread::jpeg2000parse(wxFile *fileid, wxFileOffset filepoint, wxFile int LBox_read; char TBox[5] = "\0\0\0\0"; int TBox_read; - __int64 XLBox = 0x0000000000000000; + int8byte XLBox = 0x0000000000000000; int XLBox_read; unsigned long int box_length = 0; int last_box = 0, box_num = 0;