diff --git a/applications/OPJViewer/CMakeLists.txt b/applications/OPJViewer/CMakeLists.txt index adb1d873..f382b14a 100644 --- a/applications/OPJViewer/CMakeLists.txt +++ b/applications/OPJViewer/CMakeLists.txt @@ -1,25 +1,25 @@ -PROJECT(viewer CXX) - -FIND_PACKAGE(wxWidgets REQUIRED) -INCLUDE(${wxWidgets_USE_FILE}) - -INCLUDE_DIRECTORIES( - ${CMAKE_CURRENT_SOURCE_DIR}/../.. - ${CMAKE_CURRENT_SOURCE_DIR}/.. - ) - -# original flags: -# -DUSE_JPWL -DwxUSE_LIBOPENJPEG -DwxUSE_GUI=1 -DOPJ_STATIC -DOPJ_HTMLABOUT -DOPJ_INICONFIG -DUSE_JPSEC -DOPJ_MANYFORMATS -ADD_DEFINITIONS(-DwxUSE_LIBOPENJPEG -DOPENJPEG_VERSION="1.5.0") -SET(OPJV_SRCS - ${CMAKE_CURRENT_SOURCE_DIR}/source/imagjpeg2000.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/source/wxj2kparser.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/source/OPJViewer.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/source/wxjp2parser.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/source/OPJDialogs.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/source/OPJThreads.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/source/OPJAbout.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/../codec/index.c - ) -ADD_EXECUTABLE(opjviewer ${OPJV_SRCS}) -TARGET_LINK_LIBRARIES(opjviewer ${wxWidgets_LIBRARIES} openjpeg) +PROJECT(viewer CXX) + +FIND_PACKAGE(wxWidgets REQUIRED) +INCLUDE(${wxWidgets_USE_FILE}) + +INCLUDE_DIRECTORIES( + ${CMAKE_CURRENT_SOURCE_DIR}/../.. + ${CMAKE_CURRENT_SOURCE_DIR}/.. + ) + +# original flags: +# -DUSE_JPWL -DwxUSE_LIBOPENJPEG -DwxUSE_GUI=1 -DOPJ_STATIC -DOPJ_HTMLABOUT -DOPJ_INICONFIG -DUSE_JPSEC -DOPJ_MANYFORMATS +ADD_DEFINITIONS(-DwxUSE_LIBOPENJPEG -DOPENJPEG_VERSION="1.5.0") +SET(OPJV_SRCS + ${CMAKE_CURRENT_SOURCE_DIR}/source/imagjpeg2000.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/source/wxj2kparser.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/source/OPJViewer.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/source/wxjp2parser.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/source/OPJDialogs.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/source/OPJThreads.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/source/OPJAbout.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/../codec/index.c + ) +ADD_EXECUTABLE(opjviewer ${OPJV_SRCS}) +TARGET_LINK_LIBRARIES(opjviewer ${wxWidgets_LIBRARIES} openjpeg) diff --git a/applications/OPJViewer/OPJViewer.iss b/applications/OPJViewer/OPJViewer.iss index d4cfadbb..0cf20da9 100644 --- a/applications/OPJViewer/OPJViewer.iss +++ b/applications/OPJViewer/OPJViewer.iss @@ -1,48 +1,48 @@ -; Script generated by the Inno Setup Script Wizard. -; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES! - -[Setup] -AppName=OPJViewer -AppVerName=OPJViewer 0.4 beta -AppPublisher=OpenJPEG -AppPublisherURL=http://www.openjpeg.org -AppSupportURL=http://www.openjpeg.org -AppUpdatesURL=http://www.openjpeg.org -DefaultDirName={pf}\OPJViewer -DefaultGroupName=OPJViewer -OutputDir=setup -OutputBaseFilename=OPJViewer04beta_setup -Compression=lzma -SolidCompression=true -InfoBeforeFile=source\readmebefore.txt -InfoAfterFile=source\readmeafter.txt -LicenseFile=source\license.txt -VersionInfoVersion=0.4.0.0 -VersionInfoCompany=OpenJPEG -VersionInfoDescription=JPEG 2000 viewer -ShowLanguageDialog=yes -SetupIconFile=source\OPJViewer.ico - -[Languages] -Name: english; MessagesFile: compiler:Default.isl - -[Tasks] -Name: desktopicon; Description: {cm:CreateDesktopIcon}; GroupDescription: {cm:AdditionalIcons}; Flags: unchecked - -[Files] -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; WorkingDir: {app}; IconIndex: 0 -Name: {group}\{cm:UninstallProgram,OPJViewer}; Filename: {uninstallexe} -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; WorkingDir: {app} - -[Registry] -Root: HKCU; Subkey: Software\OpenJPEG; ValueType: none; ValueData: 1; Flags: uninsdeletekey; Tasks: ; Languages: -Root: HKCU; Subkey: Software\OpenJPEG\OPJViewer; ValueType: none; ValueData: 1; Flags: uninsdeletekey; Tasks: ; Languages: +; Script generated by the Inno Setup Script Wizard. +; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES! + +[Setup] +AppName=OPJViewer +AppVerName=OPJViewer 0.4 beta +AppPublisher=OpenJPEG +AppPublisherURL=http://www.openjpeg.org +AppSupportURL=http://www.openjpeg.org +AppUpdatesURL=http://www.openjpeg.org +DefaultDirName={pf}\OPJViewer +DefaultGroupName=OPJViewer +OutputDir=setup +OutputBaseFilename=OPJViewer04beta_setup +Compression=lzma +SolidCompression=true +InfoBeforeFile=source\readmebefore.txt +InfoAfterFile=source\readmeafter.txt +LicenseFile=source\license.txt +VersionInfoVersion=0.4.0.0 +VersionInfoCompany=OpenJPEG +VersionInfoDescription=JPEG 2000 viewer +ShowLanguageDialog=yes +SetupIconFile=source\OPJViewer.ico + +[Languages] +Name: english; MessagesFile: compiler:Default.isl + +[Tasks] +Name: desktopicon; Description: {cm:CreateDesktopIcon}; GroupDescription: {cm:AdditionalIcons}; Flags: unchecked + +[Files] +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; WorkingDir: {app}; IconIndex: 0 +Name: {group}\{cm:UninstallProgram,OPJViewer}; Filename: {uninstallexe} +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; WorkingDir: {app} + +[Registry] +Root: HKCU; Subkey: Software\OpenJPEG; ValueType: none; ValueData: 1; Flags: uninsdeletekey; Tasks: ; Languages: +Root: HKCU; Subkey: Software\OpenJPEG\OPJViewer; ValueType: none; ValueData: 1; Flags: uninsdeletekey; Tasks: ; Languages: diff --git a/applications/OPJViewer/Readme.txt b/applications/OPJViewer/Readme.txt index 7eb3e467..fe104bbf 100644 --- a/applications/OPJViewer/Readme.txt +++ b/applications/OPJViewer/Readme.txt @@ -1,100 +1,100 @@ -=============================================================================== - JPEG2000 Visualization Software - OPJViewer - - Version 0.4 beta -=============================================================================== - - -1. Scope -============= - -This document describes the installation and use of the OPJViewer in the framework of OpenJPEG library. - -This implementation has been developed using the OpenJPEG library as decoding engine and wxWidgets 2.8 as GUI engine. - -If you find some bugs or if you have problems using the viewer, please send an e-mail to jpwl@diei.unipg.it - -2. Installing the viewer -========================== - -There are two options available, at the moment: - -a) compile from source code -b) download a precompiled binary. - -In order to use option a), it is mandatory to have compiled and built the LibOpenJPEG_JPWL library and the wxWidgets 2.8 framework (you have to download it from http://www.wxwidgets.org/ and compile the wx* libraries). - -2.1. Compiling the source code in Windows -------------------------------------------- - -The steps required to compile the viewer under windows are: - -a) Download at least the libopenjpeg, jpwl, and opjviewer folders from the SVN trunk. -b) Open the OPJViewer.dsw workspace with Visual C++ 6 and activate the "OPJViewer - Win32 Release" configuration. -c) In the configuration settings, go to the C++ tab and modify the wxWidgets paths in order to reflect your wx* install configuration (Preprocessor -> Additional include directories): simply update each instance of the two wx paths, do not remove or add them. -d) In the configuration settings, go to the Link tab and modify the wxWidgets path in order to reflect your wx* install configuration (Input -> Additional library path): simply update the wx path. -e) In the configuration settings, go to the Resources tab and modify the wxWidgets path in order to reflect your wx* install configuration (Additional resource include directories): simply update the wx path. -f) Build! -g) Run! -h) (OPTIONAL) Prepare an installer by compiling the InnoSetup script OPJViewer.iss (you need to download InnoSetup from http://www.jrsoftware.org/isinfo.php). - -2.1.1 Additional libraries ----------------------------- - -Since we are also working on the Digital Cinema JPEG 2000, we are integrating the viewer with the MXF library, which is used to prepare the DCPs for digital movies. You can enable its linking in the code by specifying the USE_MXF preprocessor directive but, remember, the integration is at a very early stage. - -2.2. Compiling the source code in Unix-like systems ------------------------------------------------------ - -The porting is possible and under way. - - -3. General information on the viewer -==================================== - -This viewer is conceived to open and display information and image content of J2K, JP2, and MJ2 files. -The viewer application interface is divided into three main panels: -- a browsing pane; -- a viewing pane; -- a log/peek pane. - -The browsing pane will present the markers or boxes hierarchy, with position (byte number where marker/box starts and stops) and length information (i.e., inner length as signalled by marker/box and total length, with marker/box sign included), in the following form: - -filename -| -|_ #000: Marker/Box short name (Hex code) -| | -| |_ *** Marker/Box long name *** -| |_ startbyte > stopbyte, inner_length + marker/box sign length (total length) -| |_ Additional info, depending on the marker/box type -| |_ ... -| -|_ #001: Marker/Box short name (Hex code) -| | -| |_ ... -| -... - - -The viewing pane will display the decoded image contained in the JPEG 2000 file. -It should display correctly images as large as 4000x2000, provided that a couple of GB of RAM are available. Nothing is known about the display of larger sizes: let us know if you manage to get it working. - - -The log/peek pane is shared among two different subpanels: - -- the log panel will report a lot of debugging info coming out from the wx GUI as well as from the openjpeg library -- the peek pane tries to give a peek on the codestream/file portion which is currently selected in the browsing pane. It shows both hex and ascii values corresponding to the marker/box section. - - -4. Known bugs and limitations -=============================== - -4.1. Bugs ------------ - -* - -4.2. Limitations ------------------- - -* For mj2 files, rendering is only in B/W +=============================================================================== + JPEG2000 Visualization Software - OPJViewer + + Version 0.4 beta +=============================================================================== + + +1. Scope +============= + +This document describes the installation and use of the OPJViewer in the framework of OpenJPEG library. + +This implementation has been developed using the OpenJPEG library as decoding engine and wxWidgets 2.8 as GUI engine. + +If you find some bugs or if you have problems using the viewer, please send an e-mail to jpwl@diei.unipg.it + +2. Installing the viewer +========================== + +There are two options available, at the moment: + +a) compile from source code +b) download a precompiled binary. + +In order to use option a), it is mandatory to have compiled and built the LibOpenJPEG_JPWL library and the wxWidgets 2.8 framework (you have to download it from http://www.wxwidgets.org/ and compile the wx* libraries). + +2.1. Compiling the source code in Windows +------------------------------------------- + +The steps required to compile the viewer under windows are: + +a) Download at least the libopenjpeg, jpwl, and opjviewer folders from the SVN trunk. +b) Open the OPJViewer.dsw workspace with Visual C++ 6 and activate the "OPJViewer - Win32 Release" configuration. +c) In the configuration settings, go to the C++ tab and modify the wxWidgets paths in order to reflect your wx* install configuration (Preprocessor -> Additional include directories): simply update each instance of the two wx paths, do not remove or add them. +d) In the configuration settings, go to the Link tab and modify the wxWidgets path in order to reflect your wx* install configuration (Input -> Additional library path): simply update the wx path. +e) In the configuration settings, go to the Resources tab and modify the wxWidgets path in order to reflect your wx* install configuration (Additional resource include directories): simply update the wx path. +f) Build! +g) Run! +h) (OPTIONAL) Prepare an installer by compiling the InnoSetup script OPJViewer.iss (you need to download InnoSetup from http://www.jrsoftware.org/isinfo.php). + +2.1.1 Additional libraries +---------------------------- + +Since we are also working on the Digital Cinema JPEG 2000, we are integrating the viewer with the MXF library, which is used to prepare the DCPs for digital movies. You can enable its linking in the code by specifying the USE_MXF preprocessor directive but, remember, the integration is at a very early stage. + +2.2. Compiling the source code in Unix-like systems +----------------------------------------------------- + +The porting is possible and under way. + + +3. General information on the viewer +==================================== + +This viewer is conceived to open and display information and image content of J2K, JP2, and MJ2 files. +The viewer application interface is divided into three main panels: +- a browsing pane; +- a viewing pane; +- a log/peek pane. + +The browsing pane will present the markers or boxes hierarchy, with position (byte number where marker/box starts and stops) and length information (i.e., inner length as signalled by marker/box and total length, with marker/box sign included), in the following form: + +filename +| +|_ #000: Marker/Box short name (Hex code) +| | +| |_ *** Marker/Box long name *** +| |_ startbyte > stopbyte, inner_length + marker/box sign length (total length) +| |_ Additional info, depending on the marker/box type +| |_ ... +| +|_ #001: Marker/Box short name (Hex code) +| | +| |_ ... +| +... + + +The viewing pane will display the decoded image contained in the JPEG 2000 file. +It should display correctly images as large as 4000x2000, provided that a couple of GB of RAM are available. Nothing is known about the display of larger sizes: let us know if you manage to get it working. + + +The log/peek pane is shared among two different subpanels: + +- the log panel will report a lot of debugging info coming out from the wx GUI as well as from the openjpeg library +- the peek pane tries to give a peek on the codestream/file portion which is currently selected in the browsing pane. It shows both hex and ascii values corresponding to the marker/box section. + + +4. Known bugs and limitations +=============================== + +4.1. Bugs +----------- + +* + +4.2. Limitations +------------------ + +* For mj2 files, rendering is only in B/W diff --git a/applications/OPJViewer/about/about.htm b/applications/OPJViewer/about/about.htm index fec6028f..cdde9773 100644 --- a/applications/OPJViewer/about/about.htm +++ b/applications/OPJViewer/about/about.htm @@ -1,36 +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 -
- - + + + + + + + + + + + + + + + + + + + +
+

+
+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/applications/OPJViewer/source/OPJAbout.cpp b/applications/OPJViewer/source/OPJAbout.cpp index ecc5f45d..f988c727 100644 --- a/applications/OPJViewer/source/OPJAbout.cpp +++ b/applications/OPJViewer/source/OPJAbout.cpp @@ -1,87 +1,87 @@ -/* - * Copyright (c) 2007, Digital Signal Processing Laboratory, Universita'  degli studi di Perugia (UPG), Italy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are 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. - */ -#ifdef USE_MXF -#include "mxflib/mxflib.h" -#endif // USE_MXF - -#include "OPJViewer.h" - -// about window for the frame -void OPJFrame::OnAbout(wxCommandEvent& WXUNUSED(event)) -{ -#ifdef OPJ_HTMLABOUT -#include "about_htm.h" -#include "opj_logo.xpm" - - wxBoxSizer *topsizer; - wxHtmlWindow *html; - wxDialog dlg(this, wxID_ANY, wxString(_("About"))); - - wxMemoryFSHandler::AddFile(wxT("opj_logo.xpm"), wxBitmap(opj_logo), wxBITMAP_TYPE_XPM); - - topsizer = new wxBoxSizer(wxVERTICAL); - - html = new wxHtmlWindow(&dlg, wxID_ANY, wxDefaultPosition, wxSize(320, 250), wxHW_SCROLLBAR_NEVER); - html->SetBorders(0); - //html->LoadPage(wxT("about/about.htm")); - //html->SetPage("Hello, world!"); - html->SetPage(htmlaboutpage); - 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 ") - wxT(OPENJPEG_VERSION) - wxT("\non ") wxT(__DATE__) wxT(", ") wxT(__TIME__) - wxT("\nRunning under %s\n\n") - OPJ_APPLICATION_COPYRIGHT, - wxVERSION_STRING, - wxGetOsDescription().c_str()), - wxT("About ") OPJ_APPLICATION_NAME, - wxOK | wxICON_INFORMATION, - this - ); - -#endif - -} +/* + * Copyright (c) 2007, Digital Signal Processing Laboratory, Universita'  degli studi di Perugia (UPG), Italy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are 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. + */ +#ifdef USE_MXF +#include "mxflib/mxflib.h" +#endif // USE_MXF + +#include "OPJViewer.h" + +// about window for the frame +void OPJFrame::OnAbout(wxCommandEvent& WXUNUSED(event)) +{ +#ifdef OPJ_HTMLABOUT +#include "about_htm.h" +#include "opj_logo.xpm" + + wxBoxSizer *topsizer; + wxHtmlWindow *html; + wxDialog dlg(this, wxID_ANY, wxString(_("About"))); + + wxMemoryFSHandler::AddFile(wxT("opj_logo.xpm"), wxBitmap(opj_logo), wxBITMAP_TYPE_XPM); + + topsizer = new wxBoxSizer(wxVERTICAL); + + html = new wxHtmlWindow(&dlg, wxID_ANY, wxDefaultPosition, wxSize(320, 250), wxHW_SCROLLBAR_NEVER); + html->SetBorders(0); + //html->LoadPage(wxT("about/about.htm")); + //html->SetPage("Hello, world!"); + html->SetPage(htmlaboutpage); + 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 ") + wxT(OPENJPEG_VERSION) + wxT("\non ") wxT(__DATE__) wxT(", ") wxT(__TIME__) + wxT("\nRunning under %s\n\n") + OPJ_APPLICATION_COPYRIGHT, + wxVERSION_STRING, + wxGetOsDescription().c_str()), + wxT("About ") OPJ_APPLICATION_NAME, + wxOK | wxICON_INFORMATION, + this + ); + +#endif + +} diff --git a/applications/OPJViewer/source/OPJChild16.xpm b/applications/OPJViewer/source/OPJChild16.xpm index 48e87963..99b7b2cf 100644 --- a/applications/OPJViewer/source/OPJChild16.xpm +++ b/applications/OPJViewer/source/OPJChild16.xpm @@ -1,28 +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+", -"++++++++++++++++" -}; +/* 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/applications/OPJViewer/source/OPJDialogs.cpp b/applications/OPJViewer/source/OPJDialogs.cpp index 36490d40..ff96da9c 100644 --- a/applications/OPJViewer/source/OPJDialogs.cpp +++ b/applications/OPJViewer/source/OPJDialogs.cpp @@ -1,1373 +1,1373 @@ -/* - * Copyright (c) 2007, Digital Signal Processing Laboratory, Universita'  degli studi di Perugia (UPG), Italy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are 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. - */ -#include "OPJViewer.h" - -// ---------------------------------------------------------------------------- -// OPJDecoderDialog -// ---------------------------------------------------------------------------- - -IMPLEMENT_CLASS(OPJDecoderDialog, wxPropertySheetDialog) - -BEGIN_EVENT_TABLE(OPJDecoderDialog, wxPropertySheetDialog) - EVT_CHECKBOX(OPJDECO_ENABLEDECO, OPJDecoderDialog::OnEnableDeco) -#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); - - Create(win, wxID_ANY, wxT("Decoder settings"), - wxDefaultPosition, wxDefaultSize, - wxDEFAULT_DIALOG_STYLE| (int) wxPlatform::IfNot(wxOS_WINDOWS_CE, wxRESIZE_BORDER) - ); - - CreateButtons(wxOK | wxCANCEL | (int)wxPlatform::IfNot(wxOS_WINDOWS_CE, wxHELP)); - - m_settingsNotebook = GetBookCtrl(); - - wxPanel* mainSettings = CreateMainSettingsPage(m_settingsNotebook); - wxPanel* jpeg2000Settings = CreatePart1SettingsPage(m_settingsNotebook); - if (!wxGetApp().m_enabledeco) - jpeg2000Settings->Enable(false); - wxPanel* mjpeg2000Settings = CreatePart3SettingsPage(m_settingsNotebook); - if (!wxGetApp().m_enabledeco) - mjpeg2000Settings->Enable(false); -#ifdef USE_JPWL - wxPanel* jpwlSettings = CreatePart11SettingsPage(m_settingsNotebook); - if (!wxGetApp().m_enabledeco) - jpwlSettings->Enable(false); -#endif // USE_JPWL - - m_settingsNotebook->AddPage(mainSettings, wxT("Display"), false); - m_settingsNotebook->AddPage(jpeg2000Settings, wxT("JPEG 2000"), false); - m_settingsNotebook->AddPage(mjpeg2000Settings, wxT("MJPEG 2000"), false); -#ifdef USE_JPWL - m_settingsNotebook->AddPage(jpwlSettings, wxT("JPWL"), false); -#endif // USE_JPWL - - LayoutDialog(); -} - -OPJDecoderDialog::~OPJDecoderDialog() -{ -} - -wxPanel* OPJDecoderDialog::CreateMainSettingsPage(wxWindow* parent) -{ - wxPanel* panel = new wxPanel(parent, wxID_ANY); - - // top sizer - wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL); - - // sub top sizer - wxBoxSizer *subtopSizer = new wxBoxSizer(wxVERTICAL); - - // add decoding enabling check box - subtopSizer->Add( - m_enabledecoCheck = new wxCheckBox(panel, OPJDECO_ENABLEDECO, wxT("Enable decoding"), wxDefaultPosition, wxDefaultSize), - 0, wxGROW | wxALL, 5); - m_enabledecoCheck->SetValue(wxGetApp().m_enabledeco); - - // add parsing enabling check box - subtopSizer->Add( - m_enableparseCheck = new wxCheckBox(panel, OPJDECO_ENABLEPARSE, wxT("Enable parsing"), wxDefaultPosition, wxDefaultSize), - 0, wxGROW | wxALL, 5); - m_enableparseCheck->SetValue(wxGetApp().m_enableparse); - - // resize settings, column - wxString choices[] = {wxT("Don't resize"), wxT("Low quality"), wxT("High quality")}; - m_resizeBox = new wxRadioBox(panel, OPJDECO_RESMETHOD, - wxT("Resize method"), - wxDefaultPosition, wxDefaultSize, - WXSIZEOF(choices), - choices, - 1, - wxRA_SPECIFY_ROWS); - m_resizeBox->SetSelection(wxGetApp().m_resizemethod + 1); - - subtopSizer->Add(m_resizeBox, 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; -} - -wxPanel* OPJDecoderDialog::CreatePart3SettingsPage(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); - - // frame settings, column - wxStaticBox* frameBox = new wxStaticBox(panel, wxID_ANY, wxT("Frame")); - wxBoxSizer* frameSizer = new wxStaticBoxSizer(frameBox, wxVERTICAL); - - // selected frame number, row - wxBoxSizer* framenumSizer = new wxBoxSizer(wxHORIZONTAL); - - // add some text - framenumSizer->Add(new wxStaticText(panel, wxID_ANY, wxT("&Displayed frame:")), - 0, wxALL | wxALIGN_CENTER_VERTICAL, 5); - - // add some horizontal space - framenumSizer->Add(5, 5, 1, wxALL, 0); - - // add the value control - framenumSizer->Add( - m_framenumCtrl = new wxSpinCtrl(panel, OPJDECO_FRAMENUM, - wxString::Format(wxT("%d"), wxGetApp().m_framenum), - wxDefaultPosition, wxSize(80, wxDefaultCoord), - wxSP_ARROW_KEYS, - 1, 100000, wxGetApp().m_framenum), - 0, wxALL | wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL, 5); - - frameSizer->Add(framenumSizer, 0, wxGROW | wxALL, 5); - - subtopSizer->Add(frameSizer, 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; -} - -wxPanel* OPJDecoderDialog::CreatePart1SettingsPage(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("&Component displayed:")), - 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); - m_numcompsCtrl->Enable(true); - - 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::CreatePart11SettingsPage(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); - } - -} - -#endif // USE_JPWL - -void OPJDecoderDialog::OnEnableDeco(wxCommandEvent& event) -{ - size_t pp; - - if (event.IsChecked()) { - wxLogMessage(wxT("Decoding enabled")); - m_resizeBox->Enable(true); - // enable all tabs except ourselves - for (pp = 0; pp < m_settingsNotebook->GetPageCount(); pp++) { - if (m_settingsNotebook->GetPageText(pp) != wxT("Display")) - m_settingsNotebook->GetPage(pp)->Enable(true); - } - } else { - wxLogMessage(wxT("Decoding disabled")); - m_resizeBox->Enable(false); - // disable all tabs except ourselves - for (pp = 0; pp < m_settingsNotebook->GetPageCount(); pp++) { - if (m_settingsNotebook->GetPageText(pp) != wxT("Display")) - m_settingsNotebook->GetPage(pp)->Enable(false); - } - } - -} - - - - -// ---------------------------------------------------------------------------- -// OPJEncoderDialog -// ---------------------------------------------------------------------------- - -IMPLEMENT_CLASS(OPJEncoderDialog, wxPropertySheetDialog) - -BEGIN_EVENT_TABLE(OPJEncoderDialog, wxPropertySheetDialog) - EVT_CHECKBOX(OPJENCO_ENABLECOMM, OPJEncoderDialog::OnEnableComm) - EVT_CHECKBOX(OPJENCO_ENABLEINDEX, OPJEncoderDialog::OnEnableIdx) - EVT_CHECKBOX(OPJENCO_ENABLEPOC, OPJEncoderDialog::OnEnablePoc) - EVT_RADIOBUTTON(OPJENCO_RATERADIO, OPJEncoderDialog::OnRadioQualityRate) - EVT_RADIOBUTTON(OPJENCO_QUALITYRADIO, OPJEncoderDialog::OnRadioQualityRate) -#ifdef USE_JPWL - EVT_CHECKBOX(OPJENCO_ENABLEJPWL, OPJEncoderDialog::OnEnableJPWL) - EVT_CHOICE(OPJENCO_HPROT, OPJEncoderDialog::OnHprotSelect) - EVT_CHOICE(OPJENCO_PPROT, OPJEncoderDialog::OnPprotSelect) - EVT_CHOICE(OPJENCO_SENSI, OPJEncoderDialog::OnSensiSelect) -#endif // USE_JPWL -END_EVENT_TABLE() - -OPJEncoderDialog::OPJEncoderDialog(wxWindow* win, int dialogType) -{ - SetExtraStyle(wxDIALOG_EX_CONTEXTHELP|wxWS_EX_VALIDATE_RECURSIVELY); - - Create(win, wxID_ANY, wxT("Encoder settings"), - wxDefaultPosition, wxDefaultSize, - wxDEFAULT_DIALOG_STYLE| (int) wxPlatform::IfNot(wxOS_WINDOWS_CE, wxRESIZE_BORDER) - ); - - CreateButtons(wxOK | wxCANCEL | (int)wxPlatform::IfNot(wxOS_WINDOWS_CE, wxHELP)); - - m_settingsNotebook = GetBookCtrl(); - - wxPanel* jpeg2000_1Settings = CreatePart1_1SettingsPage(m_settingsNotebook); - wxPanel* jpeg2000_2Settings = CreatePart1_2SettingsPage(m_settingsNotebook); - wxPanel* mainSettings = CreateMainSettingsPage(m_settingsNotebook); -#ifdef USE_JPWL - wxPanel* jpwlSettings = CreatePart11SettingsPage(m_settingsNotebook); -#endif // USE_JPWL - -#ifdef USE_JPWL - m_settingsNotebook->AddPage(jpwlSettings, wxT("JPWL"), false); -#endif // USE_JPWL - m_settingsNotebook->AddPage(jpeg2000_1Settings, wxT("JPEG 2000 - 1"), false); - m_settingsNotebook->AddPage(jpeg2000_2Settings, wxT("JPEG 2000 - 2"), false); - m_settingsNotebook->AddPage(mainSettings, wxT("General"), false); - - LayoutDialog(); -} - -OPJEncoderDialog::~OPJEncoderDialog() -{ -} - -wxPanel* OPJEncoderDialog::CreateMainSettingsPage(wxWindow* parent) -{ - wxPanel* panel = new wxPanel(parent, wxID_ANY); - - // top sizer - wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL); - - // sub top sizer - wxBoxSizer *subtopSizer = new wxBoxSizer(wxVERTICAL); - - 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* OPJEncoderDialog::CreatePart11SettingsPage(wxWindow* parent) -{ - wxPanel* panel = new wxPanel(parent, wxID_ANY); - int specno; - - // top sizer - wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL); - - // add JPWL enabling check box - topSizer->Add( - m_enablejpwlCheck = new wxCheckBox(panel, OPJENCO_ENABLEJPWL, wxT("Enable JPWL"), - wxDefaultPosition, wxDefaultSize), - 0, wxGROW | wxALL | wxALIGN_CENTER, 5); - m_enablejpwlCheck->SetValue(wxGetApp().m_enablejpwle); - - // sub top sizer - wxFlexGridSizer *subtopSizer = new wxFlexGridSizer(2, 3, 3); - - // header settings, column - wxStaticBox* headerBox = new wxStaticBox(panel, wxID_ANY, wxT("Header protection")); - wxBoxSizer* headerSizer = new wxStaticBoxSizer(headerBox, wxVERTICAL); - - // info sizer, row - wxBoxSizer* info1Sizer = new wxBoxSizer(wxHORIZONTAL); - - // add some text - info1Sizer->Add(new wxStaticText(panel, wxID_ANY, - wxT("Type")), - 0, wxALL | wxALIGN_CENTER_VERTICAL, 1); - - // add some horizontal space - info1Sizer->Add(3, 3, 1, wxALL, 0); - - // add some text - info1Sizer->Add(new wxStaticText(panel, wxID_ANY, - wxT("Tile part")), - 0, wxALL | wxALIGN_CENTER_VERTICAL, 1); - - headerSizer->Add(info1Sizer, 0, wxGROW | wxALL, 0); - - // specify specs - wxString hprotvalues[] = {wxT("None"), wxT("Pred."), wxT("CRC16"), wxT("CRC32"), - wxT("RS37"), wxT("RS38"), wxT("RS40"), wxT("RS43"), wxT("RS45"), wxT("RS48"), - wxT("RS51"), wxT("RS53"), wxT("RS56"), wxT("RS64"), wxT("RS75"), wxT("RS80"), - wxT("RS85"), wxT("RS96"), wxT("RS112"), wxT("RS128")}; - for (specno = 0; specno < MYJPWL_MAX_NO_TILESPECS; specno++) { - - // tile+hprot sizer, row - wxBoxSizer* tilehprotSizer = new wxBoxSizer(wxHORIZONTAL); - - // add the value selection - tilehprotSizer->Add( - m_hprotChoice[specno] = new wxChoice(panel, OPJENCO_HPROT, - wxDefaultPosition, wxSize(60, wxDefaultCoord), - WXSIZEOF(hprotvalues), hprotvalues), - 0, wxALL | wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL, 1); - m_hprotChoice[specno]->SetSelection(wxGetApp().m_hprotsel[specno]); - - // add some horizontal space - tilehprotSizer->Add(3, 3, 1, wxALL, 0); - - // add the value control - tilehprotSizer->Add( - m_htileCtrl[specno] = new wxSpinCtrl(panel, OPJENCO_HTILE, - wxString::Format(wxT("%d"), wxGetApp().m_htileval[specno]), - wxDefaultPosition, wxSize(45, wxDefaultCoord), - wxSP_ARROW_KEYS, - 0, JPWL_MAXIMUM_TILES - 1, 0), - 0, wxALL | wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL, 1); - - headerSizer->Add(tilehprotSizer, 0, wxGROW | wxALL, 0); - } - - wxCommandEvent event1; - OnHprotSelect(event1); - - subtopSizer->Add(headerSizer, 0, wxGROW | wxALL, 3); - - // packet settings, column - wxStaticBox* packetBox = new wxStaticBox(panel, wxID_ANY, wxT("Packet protection")); - wxBoxSizer* packetSizer = new wxStaticBoxSizer(packetBox, wxVERTICAL); - - // info sizer, row - wxBoxSizer* info2Sizer = new wxBoxSizer(wxHORIZONTAL); - - // add some text - info2Sizer->Add(new wxStaticText(panel, wxID_ANY, - wxT("Type")), - 0, wxALL | wxALIGN_CENTER_VERTICAL, 1); - - // add some horizontal space - info2Sizer->Add(3, 3, 1, wxALL, 0); - - // add some text - info2Sizer->Add(new wxStaticText(panel, wxID_ANY, - wxT("Tile part")), - 0, wxALL | wxALIGN_CENTER_VERTICAL, 1); - - // add some horizontal space - info2Sizer->Add(3, 3, 1, wxALL, 0); - - // add some text - info2Sizer->Add(new wxStaticText(panel, wxID_ANY, - wxT("Packet")), - 0, wxALL | wxALIGN_CENTER_VERTICAL, 1); - - packetSizer->Add(info2Sizer, 0, wxGROW | wxALL, 0); - - // specify specs - wxString pprotvalues[] = {wxT("None"), wxT("Pred."), wxT("CRC16"), wxT("CRC32"), - wxT("RS37"), wxT("RS38"), wxT("RS40"), wxT("RS43"), wxT("RS45"), wxT("RS48"), - wxT("RS51"), wxT("RS53"), wxT("RS56"), wxT("RS64"), wxT("RS75"), wxT("RS80"), - wxT("RS85"), wxT("RS96"), wxT("RS112"), wxT("RS128")}; - for (specno = 0; specno < MYJPWL_MAX_NO_TILESPECS; specno++) { - - // tile+pprot sizer, row - wxBoxSizer* tilepprotSizer = new wxBoxSizer(wxHORIZONTAL); - - // add the value selection - tilepprotSizer->Add( - m_pprotChoice[specno] = new wxChoice(panel, OPJENCO_PPROT, - wxDefaultPosition, wxSize(60, wxDefaultCoord), - WXSIZEOF(pprotvalues), pprotvalues), - 0, wxALL | wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL, 1); - m_pprotChoice[specno]->SetSelection(wxGetApp().m_pprotsel[specno]); - - // add some horizontal space - tilepprotSizer->Add(3, 3, 1, wxALL, 0); - - // add the value control - tilepprotSizer->Add( - m_ptileCtrl[specno] = new wxSpinCtrl(panel, OPJENCO_PTILE, - wxString::Format(wxT("%d"), wxGetApp().m_ptileval[specno]), - wxDefaultPosition, wxSize(45, wxDefaultCoord), - wxSP_ARROW_KEYS, - 0, JPWL_MAXIMUM_TILES - 1, 0), - 0, wxALL | wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL, 1); - - // add some horizontal space - tilepprotSizer->Add(3, 3, 1, wxALL, 0); - - // add the value control - tilepprotSizer->Add( - m_ppackCtrl[specno] = new wxSpinCtrl(panel, OPJENCO_PPACK, - wxString::Format(wxT("%d"), wxGetApp().m_ppackval[specno]), - wxDefaultPosition, wxSize(50, wxDefaultCoord), - wxSP_ARROW_KEYS, - 0, 2047, 0), - 0, wxALL | wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL, 1); - - packetSizer->Add(tilepprotSizer, 0, wxGROW | wxALL, 0); - } - - wxCommandEvent event2; - OnPprotSelect(event2); - - subtopSizer->Add(packetSizer, 0, wxGROW | wxALL, 3); - - // sensitivity settings, column - wxStaticBox* sensiBox = new wxStaticBox(panel, wxID_ANY, wxT("Sensitivity")); - wxBoxSizer* sensiSizer = new wxStaticBoxSizer(sensiBox, wxVERTICAL); - - // info sizer, row - wxBoxSizer* info3Sizer = new wxBoxSizer(wxHORIZONTAL); - - // add some text - info3Sizer->Add(new wxStaticText(panel, wxID_ANY, - wxT("Type")), - 0, wxALL | wxALIGN_CENTER_VERTICAL, 1); - - // add some horizontal space - info3Sizer->Add(3, 3, 1, wxALL, 0); - - // add some text - info3Sizer->Add(new wxStaticText(panel, wxID_ANY, - wxT("Tile part")), - 0, wxALL | wxALIGN_CENTER_VERTICAL, 1); - - sensiSizer->Add(info3Sizer, 0, wxGROW | wxALL, 0); - - // specify specs - wxString sensivalues[] = {wxT("None"), wxT("RELATIVE ERROR"), wxT("MSE"), - wxT("MSE REDUCTION"), wxT("PSNR INCREMENT"), wxT("MAXERR"), wxT("TSE")}; - for (specno = 0; specno < MYJPWL_MAX_NO_TILESPECS; specno++) { - - // tile+sensi sizer, row - wxBoxSizer* tilesensiSizer = new wxBoxSizer(wxHORIZONTAL); - - // add the value selection - tilesensiSizer->Add( - m_sensiChoice[specno] = new wxChoice(panel, OPJENCO_SENSI, - wxDefaultPosition, wxSize(110, wxDefaultCoord), - WXSIZEOF(sensivalues), sensivalues), - 0, wxALL | wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL, 1); - m_sensiChoice[specno]->SetSelection(wxGetApp().m_sensisel[specno]); - - // add some horizontal space - tilesensiSizer->Add(3, 3, 1, wxALL, 0); - - // add the value control - tilesensiSizer->Add( - m_stileCtrl[specno] = new wxSpinCtrl(panel, OPJENCO_STILE, - wxString::Format(wxT("%d"), wxGetApp().m_stileval[specno]), - wxDefaultPosition, wxSize(45, wxDefaultCoord), - wxSP_ARROW_KEYS, - 0, JPWL_MAXIMUM_TILES - 1, 0), - 0, wxALL | wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL, 1); - - sensiSizer->Add(tilesensiSizer, 0, wxGROW | wxALL, 0); - } - - wxCommandEvent event3; - OnSensiSelect(event3); - - subtopSizer->Add(sensiSizer, 0, wxGROW | wxALL, 3); - - topSizer->Add(subtopSizer, 1, wxGROW | wxALIGN_CENTRE | wxALL, 5); - - // assign top and fit it - panel->SetSizer(topSizer); - topSizer->Fit(panel); - - return panel; -} -#endif // USE_JPWL - -wxPanel* OPJEncoderDialog::CreatePart1_1SettingsPage(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 - wxFlexGridSizer *subtopSizer = new wxFlexGridSizer(2, 3, 3); - - // image settings, column - wxStaticBox* imageBox = new wxStaticBox(panel, wxID_ANY, wxT("Image")); - wxBoxSizer* imageSizer = new wxStaticBoxSizer(imageBox, wxVERTICAL); - - // subsampling factor sizer, row - wxBoxSizer* subsSizer = new wxBoxSizer(wxHORIZONTAL); - - // add some text - subsSizer->Add(new wxStaticText(panel, wxID_ANY, wxT("&Subsampling:")), - 0, wxALL | wxALIGN_CENTER_VERTICAL, 3); - - // add some horizontal space - subsSizer->Add(3, 3, 1, wxALL, 0); - - // add the value control - subsSizer->Add( - m_subsamplingCtrl = new wxTextCtrl(panel, OPJENCO_SUBSAMPLING, - wxGetApp().m_subsampling, - wxDefaultPosition, wxSize(80, wxDefaultCoord), - wxTE_LEFT), - 0, wxALL | wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL, 3); - - imageSizer->Add(subsSizer, 0, wxGROW | wxALL, 3); - - // origin sizer, row - wxBoxSizer* imorigSizer = new wxBoxSizer(wxHORIZONTAL); - - // add some text - imorigSizer->Add(new wxStaticText(panel, wxID_ANY, wxT("&Origin:")), - 0, wxALL | wxALIGN_CENTER_VERTICAL, 3); - - // add some horizontal space - imorigSizer->Add(3, 3, 1, wxALL, 0); - - // add the value control - imorigSizer->Add( - m_originCtrl = new wxTextCtrl(panel, OPJENCO_IMORIG, - wxGetApp().m_origin, - wxDefaultPosition, wxSize(80, wxDefaultCoord), - wxTE_LEFT), - 0, wxALL | wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL, 3); - - imageSizer->Add(imorigSizer, 0, wxGROW | wxALL, 3); - - subtopSizer->Add(imageSizer, 0, wxGROW | wxALL, 3); - - // layer settings, column - wxStaticBox* layerBox = new wxStaticBox(panel, wxID_ANY, wxT("Layers/compression")); - wxBoxSizer* layerSizer = new wxStaticBoxSizer(layerBox, wxVERTICAL); - - // rate factor sizer, row - wxBoxSizer* rateSizer = new wxBoxSizer(wxHORIZONTAL); - - // add some text - /*rateSizer->Add(new wxStaticText(panel, wxID_ANY, wxT("&Rate values:")), - 0, wxALL | wxALIGN_CENTER_VERTICAL, 3);*/ - - // add the radio button - rateSizer->Add( - m_rateRadio = new wxRadioButton(panel, OPJENCO_RATERADIO, wxT("&Rate values"), - wxDefaultPosition, wxDefaultSize, - wxRB_GROUP), - 0, wxALL | wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL - ); - m_rateRadio->SetValue(!(wxGetApp().m_enablequality)); - - // add some horizontal space - rateSizer->Add(3, 3, 1, wxALL, 0); - - // add the value control - rateSizer->Add( - m_rateCtrl = new wxTextCtrl(panel, OPJENCO_RATEFACTOR, - wxGetApp().m_rates, - wxDefaultPosition, wxSize(100, wxDefaultCoord), - wxTE_LEFT), - 0, wxALL | wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL, 3); - if (wxGetApp().m_enablequality == true) - m_rateCtrl->Enable(false); - - layerSizer->Add(rateSizer, 0, wxGROW | wxALL, 3); - - // quality factor sizer, row - wxBoxSizer* qualitySizer = new wxBoxSizer(wxHORIZONTAL); - - // add some text - /*qualitySizer->Add(new wxStaticText(panel, wxID_ANY, wxT("&Quality values:")), - 0, wxALL | wxALIGN_CENTER_VERTICAL, 3);*/ - - // add the radio button - qualitySizer->Add( - m_qualityRadio = new wxRadioButton(panel, OPJENCO_QUALITYRADIO, wxT("&Quality values"), - wxDefaultPosition, wxDefaultSize), - 0, wxALL | wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL - ); - m_qualityRadio->SetValue(wxGetApp().m_enablequality); - - // add some horizontal space - qualitySizer->Add(3, 3, 1, wxALL, 0); - - // add the value control - qualitySizer->Add( - m_qualityCtrl = new wxTextCtrl(panel, OPJENCO_QUALITYFACTOR, - wxGetApp().m_quality, - wxDefaultPosition, wxSize(100, wxDefaultCoord), - wxTE_LEFT), - 0, wxALL | wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL, 3); - if (wxGetApp().m_enablequality == false) - m_qualityCtrl->Enable(false); - - layerSizer->Add(qualitySizer, 0, wxGROW | wxALL, 3); - - subtopSizer->Add(layerSizer, 0, wxGROW | wxALL, 3); - - // wavelet settings, column - wxStaticBox* transformBox = new wxStaticBox(panel, wxID_ANY, wxT("Transforms")); - wxBoxSizer* transformSizer = new wxStaticBoxSizer(transformBox, wxVERTICAL); - - // multiple component check box - transformSizer->Add( - m_mctCheck = new wxCheckBox(panel, OPJENCO_ENABLEMCT, wxT("Multiple component"), - wxDefaultPosition, wxDefaultSize), - 0, wxGROW | wxALL, 3); - m_mctCheck->SetValue(wxGetApp().m_multicomp); - - // irreversible wavelet check box - transformSizer->Add( - m_irrevCheck = new wxCheckBox(panel, OPJENCO_ENABLEIRREV, wxT("Irreversible wavelet"), - wxDefaultPosition, wxDefaultSize), - 0, wxGROW | wxALL, 3); - m_irrevCheck->SetValue(wxGetApp().m_irreversible); - - // resolution number sizer, row - wxBoxSizer* resnumSizer = new wxBoxSizer(wxHORIZONTAL); - - // add some text - resnumSizer->Add(new wxStaticText(panel, wxID_ANY, wxT("&Resolutions:")), - 0, wxALL | wxALIGN_CENTER_VERTICAL, 3); - - // add some horizontal space - resnumSizer->Add(3, 3, 1, wxALL, 0); - - // add the value control - resnumSizer->Add( - m_resolutionsCtrl = new wxSpinCtrl(panel, OPJENCO_RESNUMBER, - wxString::Format(wxT("%d"), wxGetApp().m_resolutions), - wxDefaultPosition, wxSize(80, wxDefaultCoord), - wxSP_ARROW_KEYS, - 1, 256, 6), - 0, wxALL | wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL, 3); - - transformSizer->Add(resnumSizer, 0, wxGROW | wxALL, 3); - - subtopSizer->Add(transformSizer, 0, wxGROW | wxALL, 3); - - // codestream settings, column - wxStaticBox* codestreamBox = new wxStaticBox(panel, wxID_ANY, wxT("Codestream")); - wxBoxSizer* codestreamSizer = new wxStaticBoxSizer(codestreamBox, wxVERTICAL); - - // codeblock sizer, row - wxBoxSizer* codeblockSizer = new wxBoxSizer(wxHORIZONTAL); - - // add some text - codeblockSizer->Add(new wxStaticText(panel, wxID_ANY, wxT("&Codeblocks size:")), - 0, wxALL | wxALIGN_CENTER_VERTICAL, 3); - - // add some horizontal space - codeblockSizer->Add(3, 3, 1, wxALL, 0); - - // add the value control - codeblockSizer->Add( - m_cbsizeCtrl = new wxTextCtrl(panel, OPJENCO_CODEBLOCKSIZE, - wxGetApp().m_cbsize, - wxDefaultPosition, wxSize(100, wxDefaultCoord), - wxTE_LEFT), - 0, wxALL | wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL, 3); - - codestreamSizer->Add(codeblockSizer, 0, wxGROW | wxALL, 3); - - // precinct sizer, row - wxBoxSizer* precinctSizer = new wxBoxSizer(wxHORIZONTAL); - - // add some text - precinctSizer->Add(new wxStaticText(panel, wxID_ANY, wxT("&Precincts size:")), - 0, wxALL | wxALIGN_CENTER_VERTICAL, 3); - - // add some horizontal space - precinctSizer->Add(3, 3, 1, wxALL, 0); - - // add the value control - precinctSizer->Add( - m_prsizeCtrl = new wxTextCtrl(panel, OPJENCO_PRECINCTSIZE, - wxGetApp().m_prsize, - wxDefaultPosition, wxSize(100, wxDefaultCoord), - wxTE_LEFT), - 0, wxALL | wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL, 3); - - codestreamSizer->Add(precinctSizer, 0, wxGROW | wxALL, 3); - - subtopSizer->Add(codestreamSizer, 0, wxGROW | wxALL, 3); - - // tile settings, column - wxStaticBox* tileBox = new wxStaticBox(panel, wxID_ANY, wxT("Tiles")); - wxBoxSizer* tileSizer = new wxStaticBoxSizer(tileBox, wxVERTICAL); - - // tile size sizer, row - wxBoxSizer* tilesizeSizer = new wxBoxSizer(wxHORIZONTAL); - - // add some text - tilesizeSizer->Add(new wxStaticText(panel, wxID_ANY, wxT("&Size:")), - 0, wxALL | wxALIGN_CENTER_VERTICAL, 3); - - // add some horizontal space - tilesizeSizer->Add(3, 3, 1, wxALL, 0); - - // add the value control - tilesizeSizer->Add( - m_tsizeCtrl = new wxTextCtrl(panel, OPJENCO_TILESIZE, - wxGetApp().m_tsize, - wxDefaultPosition, wxSize(80, wxDefaultCoord), - wxTE_LEFT), - 0, wxALL | wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL, 3); - - tileSizer->Add(tilesizeSizer, 0, wxGROW | wxALL, 3); - - // tile origin sizer, row - wxBoxSizer* tilorigSizer = new wxBoxSizer(wxHORIZONTAL); - - // add some text - tilorigSizer->Add(new wxStaticText(panel, wxID_ANY, wxT("&Origin:")), - 0, wxALL | wxALIGN_CENTER_VERTICAL, 3); - - // add some horizontal space - tilorigSizer->Add(3, 3, 1, wxALL, 0); - - // add the value control - tilorigSizer->Add( - m_toriginCtrl = new wxTextCtrl(panel, OPJENCO_TILORIG, - wxGetApp().m_torigin, - wxDefaultPosition, wxSize(80, wxDefaultCoord), - wxTE_LEFT), - 0, wxALL | wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL, 3); - - tileSizer->Add(tilorigSizer, 0, wxGROW | wxALL, 3); - - subtopSizer->Add(tileSizer, 0, wxGROW | wxALL, 3); - - // progression and profile settings, column - wxString choices[] = {wxT("LRCP"), wxT("RLCP"), wxT("RPCL"), wxT("PCRL"), wxT("CPRL"), - wxT("DCI2K24"), wxT("DCI2K48"), wxT("DCI4K")}; - progressionBox = new wxRadioBox(panel, OPJENCO_PROGRESSION, - wxT("Progression order/profile"), - wxDefaultPosition, wxDefaultSize, - WXSIZEOF(choices), - choices, - 3, - wxRA_SPECIFY_COLS); - progressionBox->SetSelection(wxGetApp().m_progression); - - subtopSizer->Add(progressionBox, 0, wxGROW | wxALL, 3); - - topSizer->Add(subtopSizer, 1, wxGROW | wxALIGN_CENTRE | wxALL, 5); - - // assign top and fit it - panel->SetSizer(topSizer); - topSizer->Fit(panel); - - return panel; -} - -wxPanel* OPJEncoderDialog::CreatePart1_2SettingsPage(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 - wxFlexGridSizer *subtopSizer = new wxFlexGridSizer(2, 3, 3); - - // resilience settings, column - wxStaticBox* resilBox = new wxStaticBox(panel, wxID_ANY, wxT("Error resilience")); - wxBoxSizer* resilSizer = new wxStaticBoxSizer(resilBox, wxVERTICAL); - - // resil2 sizer, row - wxBoxSizer* resil2Sizer = new wxBoxSizer(wxHORIZONTAL); - - // SOP check box - resil2Sizer->Add( - m_sopCheck = new wxCheckBox(panel, OPJENCO_ENABLESOP, wxT("SOP"), - wxDefaultPosition, wxDefaultSize), - 0, wxGROW | wxALL, 3); - m_sopCheck->SetValue(wxGetApp().m_enablesop); - - // EPH check box - resil2Sizer->Add( - m_ephCheck = new wxCheckBox(panel, OPJENCO_ENABLEEPH, wxT("EPH"), - wxDefaultPosition, wxDefaultSize), - 0, wxGROW | wxALL, 3); - m_ephCheck->SetValue(wxGetApp().m_enableeph); - - resilSizer->Add(resil2Sizer, 0, wxGROW | wxALL, 3); - - // separation - resilSizer->Add(new wxStaticLine(panel, wxID_ANY), 0, wxEXPAND | wxLEFT | wxRIGHT, 3); - - // resil3 sizer, row - wxFlexGridSizer* resil3Sizer = new wxFlexGridSizer(3, 3, 3); - - // BYPASS check box - resil3Sizer->Add( - m_enablebypassCheck = new wxCheckBox(panel, OPJENCO_ENABLEBYPASS, wxT("BYPASS"), - wxDefaultPosition, wxDefaultSize), - 0, wxGROW | wxALL, 3); - m_enablebypassCheck->SetValue(wxGetApp().m_enablebypass); - - // RESET check box - resil3Sizer->Add( - m_enableresetCheck = new wxCheckBox(panel, OPJENCO_ENABLERESET, wxT("RESET"), - wxDefaultPosition, wxDefaultSize), - 0, wxGROW | wxALL, 3); - m_enableresetCheck->SetValue(wxGetApp().m_enablereset); - - // RESTART check box - resil3Sizer->Add( - m_enablerestartCheck = new wxCheckBox(panel, OPJENCO_ENABLERESTART, wxT("RESTART"), - wxDefaultPosition, wxDefaultSize), - 0, wxGROW | wxALL, 3); - m_enablerestartCheck->SetValue(wxGetApp().m_enablerestart); - - // VSC check box - resil3Sizer->Add( - m_enablevscCheck = new wxCheckBox(panel, OPJENCO_ENABLEVSC, wxT("VSC"), - wxDefaultPosition, wxDefaultSize), - 0, wxGROW | wxALL, 3); - m_enablevscCheck->SetValue(wxGetApp().m_enablevsc); - - // ERTERM check box - resil3Sizer->Add( - m_enableertermCheck = new wxCheckBox(panel, OPJENCO_ENABLEERTERM, wxT("ERTERM"), - wxDefaultPosition, wxDefaultSize), - 0, wxGROW | wxALL, 3); - m_enableertermCheck->SetValue(wxGetApp().m_enableerterm); - - // SEGMARK check box - resil3Sizer->Add( - m_enablesegmarkCheck = new wxCheckBox(panel, OPJENCO_ENABLESEGMARK, wxT("SEGMARK"), - wxDefaultPosition, wxDefaultSize), - 0, wxGROW | wxALL, 3); - m_enablesegmarkCheck->SetValue(wxGetApp().m_enablesegmark); - - resilSizer->Add(resil3Sizer, 0, wxGROW | wxALL, 3); - - subtopSizer->Add(resilSizer, 0, wxGROW | wxALL, 3); - - // ROI settings, column - wxStaticBox* roiBox = new wxStaticBox(panel, wxID_ANY, wxT("Region Of Interest")); - wxBoxSizer* roiSizer = new wxStaticBoxSizer(roiBox, wxVERTICAL); - - // component number sizer, row - wxBoxSizer* roicompSizer = new wxBoxSizer(wxHORIZONTAL); - - // add some text - roicompSizer->Add(new wxStaticText(panel, wxID_ANY, wxT("&Component:")), - 0, wxALL | wxALIGN_CENTER_VERTICAL, 3); - - // add some horizontal space - roicompSizer->Add(3, 3, 1, wxALL, 0); - - // add the value control - roicompSizer->Add( - /*m_layerCtrl =*/ new wxSpinCtrl(panel, OPJENCO_ROICOMP, - wxT("0"), - wxDefaultPosition, wxSize(80, wxDefaultCoord), - wxSP_ARROW_KEYS, - 0, 256, 0), - 0, wxALL | wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL, 3); - - roiSizer->Add(roicompSizer, 0, wxGROW | wxALL, 3); - - // upshift sizer, row - wxBoxSizer* roishiftSizer = new wxBoxSizer(wxHORIZONTAL); - - // add some text - roishiftSizer->Add(new wxStaticText(panel, wxID_ANY, wxT("&Upshift:")), - 0, wxALL | wxALIGN_CENTER_VERTICAL, 3); - - // add some horizontal space - roishiftSizer->Add(3, 3, 1, wxALL, 0); - - // add the value control - roishiftSizer->Add( - /*m_layerCtrl =*/ new wxSpinCtrl(panel, OPJENCO_ROISHIFT, - wxT("0"), - wxDefaultPosition, wxSize(80, wxDefaultCoord), - wxSP_ARROW_KEYS, - 0, 37, 0), - 0, wxALL | wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL, 3); - - roiSizer->Add(roishiftSizer, 0, wxGROW | wxALL, 3); - - subtopSizer->Add(roiSizer, 0, wxGROW | wxALL, 3); - - // POC settings, column - wxStaticBox* pocBox = new wxStaticBox(panel, wxID_ANY, wxT("POC")); - wxBoxSizer* pocSizer = new wxStaticBoxSizer(pocBox, wxVERTICAL); - - // POC check box - pocSizer->Add( - m_enablepocCheck = new wxCheckBox(panel, OPJENCO_ENABLEPOC, wxT("Enabled (tn=rs,cs,le,re,ce,pr)"), - wxDefaultPosition, wxDefaultSize), - 0, wxGROW | wxALL, 3); - m_enablepocCheck->SetValue(wxGetApp().m_enablepoc); - - // POC sizer, row - wxBoxSizer* pocspecSizer = new wxBoxSizer(wxHORIZONTAL); - - // add some text - pocspecSizer->Add(new wxStaticText(panel, wxID_ANY, wxT("&Changes:")), - 0, wxALL | wxALIGN_TOP, 3); - - // add some horizontal space - pocspecSizer->Add(3, 3, 1, wxALL, 0); - - // add the value control - pocspecSizer->Add( - m_pocCtrl = new wxTextCtrl(panel, OPJENCO_POCSPEC, - wxGetApp().m_poc, - wxDefaultPosition, wxSize(140, 60), - wxTE_LEFT | wxTE_MULTILINE), - 0, wxALL | wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL, 3); - m_pocCtrl->Enable(wxGetApp().m_enablepoc); - - pocSizer->Add(pocspecSizer, 0, wxGROW | wxALL, 3); - - subtopSizer->Add(pocSizer, 0, wxGROW | wxALL, 3); - - // Comment settings, column - wxStaticBox* commentBox = new wxStaticBox(panel, wxID_ANY, wxT("Comment")); - wxBoxSizer* commentSizer = new wxStaticBoxSizer(commentBox, wxVERTICAL); - - // commenting check box - commentSizer->Add( - m_enablecommCheck = new wxCheckBox(panel, OPJENCO_ENABLECOMM, wxT("Enabled (empty to reset)"), - wxDefaultPosition, wxDefaultSize), - 0, wxGROW | wxALL, 3); - m_enablecommCheck->SetValue(wxGetApp().m_enablecomm); - - // add some horizontal space - commentSizer->Add(3, 3, 1, wxALL, 0); - - // add the value control - commentSizer->Add( - m_commentCtrl = new wxTextCtrl(panel, OPJENCO_COMMENTTEXT, - wxGetApp().m_comment, - wxDefaultPosition, wxSize(wxDefaultCoord, 60), - wxTE_LEFT | wxTE_MULTILINE), - 0, wxGROW | wxALL | wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL, 3); - m_commentCtrl->Enable(wxGetApp().m_enablecomm); - - subtopSizer->Add(commentSizer, 0, wxGROW | wxALL, 3); - - // Index file settings, column - wxStaticBox* indexBox = new wxStaticBox(panel, wxID_ANY, wxT("Indexing")); - wxBoxSizer* indexSizer = new wxStaticBoxSizer(indexBox, wxVERTICAL); - - // indexing check box - indexSizer->Add( - m_enableidxCheck = new wxCheckBox(panel, OPJENCO_ENABLEINDEX, wxT("Enabled"), - wxDefaultPosition, wxDefaultSize), - 0, wxGROW | wxALL, 3); - m_enableidxCheck->SetValue(wxGetApp().m_enableidx); - - // index file sizer, row - wxBoxSizer* indexnameSizer = new wxBoxSizer(wxHORIZONTAL); - - // add some text - indexnameSizer->Add(new wxStaticText(panel, wxID_ANY, wxT("&File name:")), - 0, wxALL | wxALIGN_CENTER_VERTICAL, 3); - - // add some horizontal space - indexnameSizer->Add(3, 3, 1, wxALL, 0); - - // add the value control - indexnameSizer->Add( - m_indexCtrl = new wxTextCtrl(panel, OPJENCO_INDEXNAME, - wxGetApp().m_index, - wxDefaultPosition, wxSize(120, wxDefaultCoord), - wxTE_LEFT), - 0, wxALL | wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL, 3); - m_indexCtrl->Enable(wxGetApp().m_enableidx); - - indexSizer->Add(indexnameSizer, 0, wxGROW | wxALL, 3); - - subtopSizer->Add(indexSizer, 0, wxGROW | wxALL, 3); - - topSizer->Add(subtopSizer, 1, wxGROW | wxALIGN_CENTRE | wxALL, 5); - - // assign top and fit it - panel->SetSizer(topSizer); - topSizer->Fit(panel); - - return panel; -} - -void OPJEncoderDialog::OnEnableComm(wxCommandEvent& event) -{ - if (event.IsChecked()) { - wxLogMessage(wxT("Comment enabled")); - m_commentCtrl->Enable(true); - } else { - wxLogMessage(wxT("Comment disabled")); - m_commentCtrl->Enable(false); - } - -} - -void OPJEncoderDialog::OnEnableIdx(wxCommandEvent& event) -{ - if (event.IsChecked()) { - wxLogMessage(wxT("Index enabled")); - m_indexCtrl->Enable(true); - } else { - wxLogMessage(wxT("Index disabled")); - m_indexCtrl->Enable(false); - } - -} - -void OPJEncoderDialog::OnEnablePoc(wxCommandEvent& event) -{ - if (event.IsChecked()) { - wxLogMessage(wxT("POC enabled")); - m_pocCtrl->Enable(true); - } else { - wxLogMessage(wxT("POC disabled")); - m_pocCtrl->Enable(false); - } - -} - -void OPJEncoderDialog::OnRadioQualityRate(wxCommandEvent& event) -{ - if (event.GetId() == OPJENCO_QUALITYRADIO) { - wxLogMessage(wxT("Quality selected")); - m_rateCtrl->Enable(false); - m_qualityCtrl->Enable(true); - } else { - wxLogMessage(wxT("Rate selected")); - m_rateCtrl->Enable(true); - m_qualityCtrl->Enable(false); - } -} - -#ifdef USE_JPWL -void OPJEncoderDialog::OnEnableJPWL(wxCommandEvent& event) -{ - int specno; - - if (event.IsChecked()) { - wxLogMessage(wxT("JPWL enabled")); - for (specno = 0; specno < MYJPWL_MAX_NO_TILESPECS; specno++) { - m_hprotChoice[specno]->Enable(true); - m_htileCtrl[specno]->Enable(true); - m_pprotChoice[specno]->Enable(true); - m_ptileCtrl[specno]->Enable(true); - m_ppackCtrl[specno]->Enable(true); - m_sensiChoice[specno]->Enable(true); - m_stileCtrl[specno]->Enable(true); - } - OnHprotSelect(event); - OnPprotSelect(event); - OnSensiSelect(event); - } else { - wxLogMessage(wxT("JPWL disabled")); - for (specno = 0; specno < MYJPWL_MAX_NO_TILESPECS; specno++) { - m_hprotChoice[specno]->Enable(false); - m_htileCtrl[specno]->Enable(false); - m_pprotChoice[specno]->Enable(false); - m_ptileCtrl[specno]->Enable(false); - m_ppackCtrl[specno]->Enable(false); - m_sensiChoice[specno]->Enable(false); - m_stileCtrl[specno]->Enable(false); - } - } - -} - -void OPJEncoderDialog::OnHprotSelect(wxCommandEvent& event) -{ - int specno; - - // deactivate properly - for (specno = MYJPWL_MAX_NO_TILESPECS - 1; specno >= 0; specno--) { - if (!m_hprotChoice[specno]->GetSelection()) { - m_hprotChoice[specno]->Enable(false); - m_htileCtrl[specno]->Enable(false); - } else - break; - } - if (specno < (MYJPWL_MAX_NO_TILESPECS - 1)) { - m_hprotChoice[specno + 1]->Enable(true); - m_htileCtrl[specno + 1]->Enable(true); - } - - //wxLogMessage(wxT("hprot changed: %d"), specno); -} - -void OPJEncoderDialog::OnPprotSelect(wxCommandEvent& event) -{ - int specno; - - // deactivate properly - for (specno = MYJPWL_MAX_NO_TILESPECS - 1; specno >= 0; specno--) { - if (!m_pprotChoice[specno]->GetSelection()) { - m_pprotChoice[specno]->Enable(false); - m_ptileCtrl[specno]->Enable(false); - m_ppackCtrl[specno]->Enable(false); - } else - break; - } - if (specno < (MYJPWL_MAX_NO_TILESPECS - 1)) { - m_pprotChoice[specno + 1]->Enable(true); - m_ptileCtrl[specno + 1]->Enable(true); - m_ppackCtrl[specno + 1]->Enable(true); - } - - //wxLogMessage(wxT("pprot changed: %d"), specno); -} - -void OPJEncoderDialog::OnSensiSelect(wxCommandEvent& event) -{ - int specno; - - // deactivate properly - for (specno = MYJPWL_MAX_NO_TILESPECS - 1; specno >= 0; specno--) { - if (!m_sensiChoice[specno]->GetSelection()) { - m_sensiChoice[specno]->Enable(false); - m_stileCtrl[specno]->Enable(false); - } else - break; - } - if (specno < (MYJPWL_MAX_NO_TILESPECS - 1)) { - m_sensiChoice[specno + 1]->Enable(true); - m_stileCtrl[specno + 1]->Enable(true); - } - - //wxLogMessage(wxT("sprot changed: %d"), specno); -} - - -#endif // USE_JPWL - +/* + * Copyright (c) 2007, Digital Signal Processing Laboratory, Universita'  degli studi di Perugia (UPG), Italy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are 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. + */ +#include "OPJViewer.h" + +// ---------------------------------------------------------------------------- +// OPJDecoderDialog +// ---------------------------------------------------------------------------- + +IMPLEMENT_CLASS(OPJDecoderDialog, wxPropertySheetDialog) + +BEGIN_EVENT_TABLE(OPJDecoderDialog, wxPropertySheetDialog) + EVT_CHECKBOX(OPJDECO_ENABLEDECO, OPJDecoderDialog::OnEnableDeco) +#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); + + Create(win, wxID_ANY, wxT("Decoder settings"), + wxDefaultPosition, wxDefaultSize, + wxDEFAULT_DIALOG_STYLE| (int) wxPlatform::IfNot(wxOS_WINDOWS_CE, wxRESIZE_BORDER) + ); + + CreateButtons(wxOK | wxCANCEL | (int)wxPlatform::IfNot(wxOS_WINDOWS_CE, wxHELP)); + + m_settingsNotebook = GetBookCtrl(); + + wxPanel* mainSettings = CreateMainSettingsPage(m_settingsNotebook); + wxPanel* jpeg2000Settings = CreatePart1SettingsPage(m_settingsNotebook); + if (!wxGetApp().m_enabledeco) + jpeg2000Settings->Enable(false); + wxPanel* mjpeg2000Settings = CreatePart3SettingsPage(m_settingsNotebook); + if (!wxGetApp().m_enabledeco) + mjpeg2000Settings->Enable(false); +#ifdef USE_JPWL + wxPanel* jpwlSettings = CreatePart11SettingsPage(m_settingsNotebook); + if (!wxGetApp().m_enabledeco) + jpwlSettings->Enable(false); +#endif // USE_JPWL + + m_settingsNotebook->AddPage(mainSettings, wxT("Display"), false); + m_settingsNotebook->AddPage(jpeg2000Settings, wxT("JPEG 2000"), false); + m_settingsNotebook->AddPage(mjpeg2000Settings, wxT("MJPEG 2000"), false); +#ifdef USE_JPWL + m_settingsNotebook->AddPage(jpwlSettings, wxT("JPWL"), false); +#endif // USE_JPWL + + LayoutDialog(); +} + +OPJDecoderDialog::~OPJDecoderDialog() +{ +} + +wxPanel* OPJDecoderDialog::CreateMainSettingsPage(wxWindow* parent) +{ + wxPanel* panel = new wxPanel(parent, wxID_ANY); + + // top sizer + wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL); + + // sub top sizer + wxBoxSizer *subtopSizer = new wxBoxSizer(wxVERTICAL); + + // add decoding enabling check box + subtopSizer->Add( + m_enabledecoCheck = new wxCheckBox(panel, OPJDECO_ENABLEDECO, wxT("Enable decoding"), wxDefaultPosition, wxDefaultSize), + 0, wxGROW | wxALL, 5); + m_enabledecoCheck->SetValue(wxGetApp().m_enabledeco); + + // add parsing enabling check box + subtopSizer->Add( + m_enableparseCheck = new wxCheckBox(panel, OPJDECO_ENABLEPARSE, wxT("Enable parsing"), wxDefaultPosition, wxDefaultSize), + 0, wxGROW | wxALL, 5); + m_enableparseCheck->SetValue(wxGetApp().m_enableparse); + + // resize settings, column + wxString choices[] = {wxT("Don't resize"), wxT("Low quality"), wxT("High quality")}; + m_resizeBox = new wxRadioBox(panel, OPJDECO_RESMETHOD, + wxT("Resize method"), + wxDefaultPosition, wxDefaultSize, + WXSIZEOF(choices), + choices, + 1, + wxRA_SPECIFY_ROWS); + m_resizeBox->SetSelection(wxGetApp().m_resizemethod + 1); + + subtopSizer->Add(m_resizeBox, 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; +} + +wxPanel* OPJDecoderDialog::CreatePart3SettingsPage(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); + + // frame settings, column + wxStaticBox* frameBox = new wxStaticBox(panel, wxID_ANY, wxT("Frame")); + wxBoxSizer* frameSizer = new wxStaticBoxSizer(frameBox, wxVERTICAL); + + // selected frame number, row + wxBoxSizer* framenumSizer = new wxBoxSizer(wxHORIZONTAL); + + // add some text + framenumSizer->Add(new wxStaticText(panel, wxID_ANY, wxT("&Displayed frame:")), + 0, wxALL | wxALIGN_CENTER_VERTICAL, 5); + + // add some horizontal space + framenumSizer->Add(5, 5, 1, wxALL, 0); + + // add the value control + framenumSizer->Add( + m_framenumCtrl = new wxSpinCtrl(panel, OPJDECO_FRAMENUM, + wxString::Format(wxT("%d"), wxGetApp().m_framenum), + wxDefaultPosition, wxSize(80, wxDefaultCoord), + wxSP_ARROW_KEYS, + 1, 100000, wxGetApp().m_framenum), + 0, wxALL | wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL, 5); + + frameSizer->Add(framenumSizer, 0, wxGROW | wxALL, 5); + + subtopSizer->Add(frameSizer, 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; +} + +wxPanel* OPJDecoderDialog::CreatePart1SettingsPage(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("&Component displayed:")), + 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); + m_numcompsCtrl->Enable(true); + + 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::CreatePart11SettingsPage(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); + } + +} + +#endif // USE_JPWL + +void OPJDecoderDialog::OnEnableDeco(wxCommandEvent& event) +{ + size_t pp; + + if (event.IsChecked()) { + wxLogMessage(wxT("Decoding enabled")); + m_resizeBox->Enable(true); + // enable all tabs except ourselves + for (pp = 0; pp < m_settingsNotebook->GetPageCount(); pp++) { + if (m_settingsNotebook->GetPageText(pp) != wxT("Display")) + m_settingsNotebook->GetPage(pp)->Enable(true); + } + } else { + wxLogMessage(wxT("Decoding disabled")); + m_resizeBox->Enable(false); + // disable all tabs except ourselves + for (pp = 0; pp < m_settingsNotebook->GetPageCount(); pp++) { + if (m_settingsNotebook->GetPageText(pp) != wxT("Display")) + m_settingsNotebook->GetPage(pp)->Enable(false); + } + } + +} + + + + +// ---------------------------------------------------------------------------- +// OPJEncoderDialog +// ---------------------------------------------------------------------------- + +IMPLEMENT_CLASS(OPJEncoderDialog, wxPropertySheetDialog) + +BEGIN_EVENT_TABLE(OPJEncoderDialog, wxPropertySheetDialog) + EVT_CHECKBOX(OPJENCO_ENABLECOMM, OPJEncoderDialog::OnEnableComm) + EVT_CHECKBOX(OPJENCO_ENABLEINDEX, OPJEncoderDialog::OnEnableIdx) + EVT_CHECKBOX(OPJENCO_ENABLEPOC, OPJEncoderDialog::OnEnablePoc) + EVT_RADIOBUTTON(OPJENCO_RATERADIO, OPJEncoderDialog::OnRadioQualityRate) + EVT_RADIOBUTTON(OPJENCO_QUALITYRADIO, OPJEncoderDialog::OnRadioQualityRate) +#ifdef USE_JPWL + EVT_CHECKBOX(OPJENCO_ENABLEJPWL, OPJEncoderDialog::OnEnableJPWL) + EVT_CHOICE(OPJENCO_HPROT, OPJEncoderDialog::OnHprotSelect) + EVT_CHOICE(OPJENCO_PPROT, OPJEncoderDialog::OnPprotSelect) + EVT_CHOICE(OPJENCO_SENSI, OPJEncoderDialog::OnSensiSelect) +#endif // USE_JPWL +END_EVENT_TABLE() + +OPJEncoderDialog::OPJEncoderDialog(wxWindow* win, int dialogType) +{ + SetExtraStyle(wxDIALOG_EX_CONTEXTHELP|wxWS_EX_VALIDATE_RECURSIVELY); + + Create(win, wxID_ANY, wxT("Encoder settings"), + wxDefaultPosition, wxDefaultSize, + wxDEFAULT_DIALOG_STYLE| (int) wxPlatform::IfNot(wxOS_WINDOWS_CE, wxRESIZE_BORDER) + ); + + CreateButtons(wxOK | wxCANCEL | (int)wxPlatform::IfNot(wxOS_WINDOWS_CE, wxHELP)); + + m_settingsNotebook = GetBookCtrl(); + + wxPanel* jpeg2000_1Settings = CreatePart1_1SettingsPage(m_settingsNotebook); + wxPanel* jpeg2000_2Settings = CreatePart1_2SettingsPage(m_settingsNotebook); + wxPanel* mainSettings = CreateMainSettingsPage(m_settingsNotebook); +#ifdef USE_JPWL + wxPanel* jpwlSettings = CreatePart11SettingsPage(m_settingsNotebook); +#endif // USE_JPWL + +#ifdef USE_JPWL + m_settingsNotebook->AddPage(jpwlSettings, wxT("JPWL"), false); +#endif // USE_JPWL + m_settingsNotebook->AddPage(jpeg2000_1Settings, wxT("JPEG 2000 - 1"), false); + m_settingsNotebook->AddPage(jpeg2000_2Settings, wxT("JPEG 2000 - 2"), false); + m_settingsNotebook->AddPage(mainSettings, wxT("General"), false); + + LayoutDialog(); +} + +OPJEncoderDialog::~OPJEncoderDialog() +{ +} + +wxPanel* OPJEncoderDialog::CreateMainSettingsPage(wxWindow* parent) +{ + wxPanel* panel = new wxPanel(parent, wxID_ANY); + + // top sizer + wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL); + + // sub top sizer + wxBoxSizer *subtopSizer = new wxBoxSizer(wxVERTICAL); + + 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* OPJEncoderDialog::CreatePart11SettingsPage(wxWindow* parent) +{ + wxPanel* panel = new wxPanel(parent, wxID_ANY); + int specno; + + // top sizer + wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL); + + // add JPWL enabling check box + topSizer->Add( + m_enablejpwlCheck = new wxCheckBox(panel, OPJENCO_ENABLEJPWL, wxT("Enable JPWL"), + wxDefaultPosition, wxDefaultSize), + 0, wxGROW | wxALL | wxALIGN_CENTER, 5); + m_enablejpwlCheck->SetValue(wxGetApp().m_enablejpwle); + + // sub top sizer + wxFlexGridSizer *subtopSizer = new wxFlexGridSizer(2, 3, 3); + + // header settings, column + wxStaticBox* headerBox = new wxStaticBox(panel, wxID_ANY, wxT("Header protection")); + wxBoxSizer* headerSizer = new wxStaticBoxSizer(headerBox, wxVERTICAL); + + // info sizer, row + wxBoxSizer* info1Sizer = new wxBoxSizer(wxHORIZONTAL); + + // add some text + info1Sizer->Add(new wxStaticText(panel, wxID_ANY, + wxT("Type")), + 0, wxALL | wxALIGN_CENTER_VERTICAL, 1); + + // add some horizontal space + info1Sizer->Add(3, 3, 1, wxALL, 0); + + // add some text + info1Sizer->Add(new wxStaticText(panel, wxID_ANY, + wxT("Tile part")), + 0, wxALL | wxALIGN_CENTER_VERTICAL, 1); + + headerSizer->Add(info1Sizer, 0, wxGROW | wxALL, 0); + + // specify specs + wxString hprotvalues[] = {wxT("None"), wxT("Pred."), wxT("CRC16"), wxT("CRC32"), + wxT("RS37"), wxT("RS38"), wxT("RS40"), wxT("RS43"), wxT("RS45"), wxT("RS48"), + wxT("RS51"), wxT("RS53"), wxT("RS56"), wxT("RS64"), wxT("RS75"), wxT("RS80"), + wxT("RS85"), wxT("RS96"), wxT("RS112"), wxT("RS128")}; + for (specno = 0; specno < MYJPWL_MAX_NO_TILESPECS; specno++) { + + // tile+hprot sizer, row + wxBoxSizer* tilehprotSizer = new wxBoxSizer(wxHORIZONTAL); + + // add the value selection + tilehprotSizer->Add( + m_hprotChoice[specno] = new wxChoice(panel, OPJENCO_HPROT, + wxDefaultPosition, wxSize(60, wxDefaultCoord), + WXSIZEOF(hprotvalues), hprotvalues), + 0, wxALL | wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL, 1); + m_hprotChoice[specno]->SetSelection(wxGetApp().m_hprotsel[specno]); + + // add some horizontal space + tilehprotSizer->Add(3, 3, 1, wxALL, 0); + + // add the value control + tilehprotSizer->Add( + m_htileCtrl[specno] = new wxSpinCtrl(panel, OPJENCO_HTILE, + wxString::Format(wxT("%d"), wxGetApp().m_htileval[specno]), + wxDefaultPosition, wxSize(45, wxDefaultCoord), + wxSP_ARROW_KEYS, + 0, JPWL_MAXIMUM_TILES - 1, 0), + 0, wxALL | wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL, 1); + + headerSizer->Add(tilehprotSizer, 0, wxGROW | wxALL, 0); + } + + wxCommandEvent event1; + OnHprotSelect(event1); + + subtopSizer->Add(headerSizer, 0, wxGROW | wxALL, 3); + + // packet settings, column + wxStaticBox* packetBox = new wxStaticBox(panel, wxID_ANY, wxT("Packet protection")); + wxBoxSizer* packetSizer = new wxStaticBoxSizer(packetBox, wxVERTICAL); + + // info sizer, row + wxBoxSizer* info2Sizer = new wxBoxSizer(wxHORIZONTAL); + + // add some text + info2Sizer->Add(new wxStaticText(panel, wxID_ANY, + wxT("Type")), + 0, wxALL | wxALIGN_CENTER_VERTICAL, 1); + + // add some horizontal space + info2Sizer->Add(3, 3, 1, wxALL, 0); + + // add some text + info2Sizer->Add(new wxStaticText(panel, wxID_ANY, + wxT("Tile part")), + 0, wxALL | wxALIGN_CENTER_VERTICAL, 1); + + // add some horizontal space + info2Sizer->Add(3, 3, 1, wxALL, 0); + + // add some text + info2Sizer->Add(new wxStaticText(panel, wxID_ANY, + wxT("Packet")), + 0, wxALL | wxALIGN_CENTER_VERTICAL, 1); + + packetSizer->Add(info2Sizer, 0, wxGROW | wxALL, 0); + + // specify specs + wxString pprotvalues[] = {wxT("None"), wxT("Pred."), wxT("CRC16"), wxT("CRC32"), + wxT("RS37"), wxT("RS38"), wxT("RS40"), wxT("RS43"), wxT("RS45"), wxT("RS48"), + wxT("RS51"), wxT("RS53"), wxT("RS56"), wxT("RS64"), wxT("RS75"), wxT("RS80"), + wxT("RS85"), wxT("RS96"), wxT("RS112"), wxT("RS128")}; + for (specno = 0; specno < MYJPWL_MAX_NO_TILESPECS; specno++) { + + // tile+pprot sizer, row + wxBoxSizer* tilepprotSizer = new wxBoxSizer(wxHORIZONTAL); + + // add the value selection + tilepprotSizer->Add( + m_pprotChoice[specno] = new wxChoice(panel, OPJENCO_PPROT, + wxDefaultPosition, wxSize(60, wxDefaultCoord), + WXSIZEOF(pprotvalues), pprotvalues), + 0, wxALL | wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL, 1); + m_pprotChoice[specno]->SetSelection(wxGetApp().m_pprotsel[specno]); + + // add some horizontal space + tilepprotSizer->Add(3, 3, 1, wxALL, 0); + + // add the value control + tilepprotSizer->Add( + m_ptileCtrl[specno] = new wxSpinCtrl(panel, OPJENCO_PTILE, + wxString::Format(wxT("%d"), wxGetApp().m_ptileval[specno]), + wxDefaultPosition, wxSize(45, wxDefaultCoord), + wxSP_ARROW_KEYS, + 0, JPWL_MAXIMUM_TILES - 1, 0), + 0, wxALL | wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL, 1); + + // add some horizontal space + tilepprotSizer->Add(3, 3, 1, wxALL, 0); + + // add the value control + tilepprotSizer->Add( + m_ppackCtrl[specno] = new wxSpinCtrl(panel, OPJENCO_PPACK, + wxString::Format(wxT("%d"), wxGetApp().m_ppackval[specno]), + wxDefaultPosition, wxSize(50, wxDefaultCoord), + wxSP_ARROW_KEYS, + 0, 2047, 0), + 0, wxALL | wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL, 1); + + packetSizer->Add(tilepprotSizer, 0, wxGROW | wxALL, 0); + } + + wxCommandEvent event2; + OnPprotSelect(event2); + + subtopSizer->Add(packetSizer, 0, wxGROW | wxALL, 3); + + // sensitivity settings, column + wxStaticBox* sensiBox = new wxStaticBox(panel, wxID_ANY, wxT("Sensitivity")); + wxBoxSizer* sensiSizer = new wxStaticBoxSizer(sensiBox, wxVERTICAL); + + // info sizer, row + wxBoxSizer* info3Sizer = new wxBoxSizer(wxHORIZONTAL); + + // add some text + info3Sizer->Add(new wxStaticText(panel, wxID_ANY, + wxT("Type")), + 0, wxALL | wxALIGN_CENTER_VERTICAL, 1); + + // add some horizontal space + info3Sizer->Add(3, 3, 1, wxALL, 0); + + // add some text + info3Sizer->Add(new wxStaticText(panel, wxID_ANY, + wxT("Tile part")), + 0, wxALL | wxALIGN_CENTER_VERTICAL, 1); + + sensiSizer->Add(info3Sizer, 0, wxGROW | wxALL, 0); + + // specify specs + wxString sensivalues[] = {wxT("None"), wxT("RELATIVE ERROR"), wxT("MSE"), + wxT("MSE REDUCTION"), wxT("PSNR INCREMENT"), wxT("MAXERR"), wxT("TSE")}; + for (specno = 0; specno < MYJPWL_MAX_NO_TILESPECS; specno++) { + + // tile+sensi sizer, row + wxBoxSizer* tilesensiSizer = new wxBoxSizer(wxHORIZONTAL); + + // add the value selection + tilesensiSizer->Add( + m_sensiChoice[specno] = new wxChoice(panel, OPJENCO_SENSI, + wxDefaultPosition, wxSize(110, wxDefaultCoord), + WXSIZEOF(sensivalues), sensivalues), + 0, wxALL | wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL, 1); + m_sensiChoice[specno]->SetSelection(wxGetApp().m_sensisel[specno]); + + // add some horizontal space + tilesensiSizer->Add(3, 3, 1, wxALL, 0); + + // add the value control + tilesensiSizer->Add( + m_stileCtrl[specno] = new wxSpinCtrl(panel, OPJENCO_STILE, + wxString::Format(wxT("%d"), wxGetApp().m_stileval[specno]), + wxDefaultPosition, wxSize(45, wxDefaultCoord), + wxSP_ARROW_KEYS, + 0, JPWL_MAXIMUM_TILES - 1, 0), + 0, wxALL | wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL, 1); + + sensiSizer->Add(tilesensiSizer, 0, wxGROW | wxALL, 0); + } + + wxCommandEvent event3; + OnSensiSelect(event3); + + subtopSizer->Add(sensiSizer, 0, wxGROW | wxALL, 3); + + topSizer->Add(subtopSizer, 1, wxGROW | wxALIGN_CENTRE | wxALL, 5); + + // assign top and fit it + panel->SetSizer(topSizer); + topSizer->Fit(panel); + + return panel; +} +#endif // USE_JPWL + +wxPanel* OPJEncoderDialog::CreatePart1_1SettingsPage(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 + wxFlexGridSizer *subtopSizer = new wxFlexGridSizer(2, 3, 3); + + // image settings, column + wxStaticBox* imageBox = new wxStaticBox(panel, wxID_ANY, wxT("Image")); + wxBoxSizer* imageSizer = new wxStaticBoxSizer(imageBox, wxVERTICAL); + + // subsampling factor sizer, row + wxBoxSizer* subsSizer = new wxBoxSizer(wxHORIZONTAL); + + // add some text + subsSizer->Add(new wxStaticText(panel, wxID_ANY, wxT("&Subsampling:")), + 0, wxALL | wxALIGN_CENTER_VERTICAL, 3); + + // add some horizontal space + subsSizer->Add(3, 3, 1, wxALL, 0); + + // add the value control + subsSizer->Add( + m_subsamplingCtrl = new wxTextCtrl(panel, OPJENCO_SUBSAMPLING, + wxGetApp().m_subsampling, + wxDefaultPosition, wxSize(80, wxDefaultCoord), + wxTE_LEFT), + 0, wxALL | wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL, 3); + + imageSizer->Add(subsSizer, 0, wxGROW | wxALL, 3); + + // origin sizer, row + wxBoxSizer* imorigSizer = new wxBoxSizer(wxHORIZONTAL); + + // add some text + imorigSizer->Add(new wxStaticText(panel, wxID_ANY, wxT("&Origin:")), + 0, wxALL | wxALIGN_CENTER_VERTICAL, 3); + + // add some horizontal space + imorigSizer->Add(3, 3, 1, wxALL, 0); + + // add the value control + imorigSizer->Add( + m_originCtrl = new wxTextCtrl(panel, OPJENCO_IMORIG, + wxGetApp().m_origin, + wxDefaultPosition, wxSize(80, wxDefaultCoord), + wxTE_LEFT), + 0, wxALL | wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL, 3); + + imageSizer->Add(imorigSizer, 0, wxGROW | wxALL, 3); + + subtopSizer->Add(imageSizer, 0, wxGROW | wxALL, 3); + + // layer settings, column + wxStaticBox* layerBox = new wxStaticBox(panel, wxID_ANY, wxT("Layers/compression")); + wxBoxSizer* layerSizer = new wxStaticBoxSizer(layerBox, wxVERTICAL); + + // rate factor sizer, row + wxBoxSizer* rateSizer = new wxBoxSizer(wxHORIZONTAL); + + // add some text + /*rateSizer->Add(new wxStaticText(panel, wxID_ANY, wxT("&Rate values:")), + 0, wxALL | wxALIGN_CENTER_VERTICAL, 3);*/ + + // add the radio button + rateSizer->Add( + m_rateRadio = new wxRadioButton(panel, OPJENCO_RATERADIO, wxT("&Rate values"), + wxDefaultPosition, wxDefaultSize, + wxRB_GROUP), + 0, wxALL | wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL + ); + m_rateRadio->SetValue(!(wxGetApp().m_enablequality)); + + // add some horizontal space + rateSizer->Add(3, 3, 1, wxALL, 0); + + // add the value control + rateSizer->Add( + m_rateCtrl = new wxTextCtrl(panel, OPJENCO_RATEFACTOR, + wxGetApp().m_rates, + wxDefaultPosition, wxSize(100, wxDefaultCoord), + wxTE_LEFT), + 0, wxALL | wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL, 3); + if (wxGetApp().m_enablequality == true) + m_rateCtrl->Enable(false); + + layerSizer->Add(rateSizer, 0, wxGROW | wxALL, 3); + + // quality factor sizer, row + wxBoxSizer* qualitySizer = new wxBoxSizer(wxHORIZONTAL); + + // add some text + /*qualitySizer->Add(new wxStaticText(panel, wxID_ANY, wxT("&Quality values:")), + 0, wxALL | wxALIGN_CENTER_VERTICAL, 3);*/ + + // add the radio button + qualitySizer->Add( + m_qualityRadio = new wxRadioButton(panel, OPJENCO_QUALITYRADIO, wxT("&Quality values"), + wxDefaultPosition, wxDefaultSize), + 0, wxALL | wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL + ); + m_qualityRadio->SetValue(wxGetApp().m_enablequality); + + // add some horizontal space + qualitySizer->Add(3, 3, 1, wxALL, 0); + + // add the value control + qualitySizer->Add( + m_qualityCtrl = new wxTextCtrl(panel, OPJENCO_QUALITYFACTOR, + wxGetApp().m_quality, + wxDefaultPosition, wxSize(100, wxDefaultCoord), + wxTE_LEFT), + 0, wxALL | wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL, 3); + if (wxGetApp().m_enablequality == false) + m_qualityCtrl->Enable(false); + + layerSizer->Add(qualitySizer, 0, wxGROW | wxALL, 3); + + subtopSizer->Add(layerSizer, 0, wxGROW | wxALL, 3); + + // wavelet settings, column + wxStaticBox* transformBox = new wxStaticBox(panel, wxID_ANY, wxT("Transforms")); + wxBoxSizer* transformSizer = new wxStaticBoxSizer(transformBox, wxVERTICAL); + + // multiple component check box + transformSizer->Add( + m_mctCheck = new wxCheckBox(panel, OPJENCO_ENABLEMCT, wxT("Multiple component"), + wxDefaultPosition, wxDefaultSize), + 0, wxGROW | wxALL, 3); + m_mctCheck->SetValue(wxGetApp().m_multicomp); + + // irreversible wavelet check box + transformSizer->Add( + m_irrevCheck = new wxCheckBox(panel, OPJENCO_ENABLEIRREV, wxT("Irreversible wavelet"), + wxDefaultPosition, wxDefaultSize), + 0, wxGROW | wxALL, 3); + m_irrevCheck->SetValue(wxGetApp().m_irreversible); + + // resolution number sizer, row + wxBoxSizer* resnumSizer = new wxBoxSizer(wxHORIZONTAL); + + // add some text + resnumSizer->Add(new wxStaticText(panel, wxID_ANY, wxT("&Resolutions:")), + 0, wxALL | wxALIGN_CENTER_VERTICAL, 3); + + // add some horizontal space + resnumSizer->Add(3, 3, 1, wxALL, 0); + + // add the value control + resnumSizer->Add( + m_resolutionsCtrl = new wxSpinCtrl(panel, OPJENCO_RESNUMBER, + wxString::Format(wxT("%d"), wxGetApp().m_resolutions), + wxDefaultPosition, wxSize(80, wxDefaultCoord), + wxSP_ARROW_KEYS, + 1, 256, 6), + 0, wxALL | wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL, 3); + + transformSizer->Add(resnumSizer, 0, wxGROW | wxALL, 3); + + subtopSizer->Add(transformSizer, 0, wxGROW | wxALL, 3); + + // codestream settings, column + wxStaticBox* codestreamBox = new wxStaticBox(panel, wxID_ANY, wxT("Codestream")); + wxBoxSizer* codestreamSizer = new wxStaticBoxSizer(codestreamBox, wxVERTICAL); + + // codeblock sizer, row + wxBoxSizer* codeblockSizer = new wxBoxSizer(wxHORIZONTAL); + + // add some text + codeblockSizer->Add(new wxStaticText(panel, wxID_ANY, wxT("&Codeblocks size:")), + 0, wxALL | wxALIGN_CENTER_VERTICAL, 3); + + // add some horizontal space + codeblockSizer->Add(3, 3, 1, wxALL, 0); + + // add the value control + codeblockSizer->Add( + m_cbsizeCtrl = new wxTextCtrl(panel, OPJENCO_CODEBLOCKSIZE, + wxGetApp().m_cbsize, + wxDefaultPosition, wxSize(100, wxDefaultCoord), + wxTE_LEFT), + 0, wxALL | wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL, 3); + + codestreamSizer->Add(codeblockSizer, 0, wxGROW | wxALL, 3); + + // precinct sizer, row + wxBoxSizer* precinctSizer = new wxBoxSizer(wxHORIZONTAL); + + // add some text + precinctSizer->Add(new wxStaticText(panel, wxID_ANY, wxT("&Precincts size:")), + 0, wxALL | wxALIGN_CENTER_VERTICAL, 3); + + // add some horizontal space + precinctSizer->Add(3, 3, 1, wxALL, 0); + + // add the value control + precinctSizer->Add( + m_prsizeCtrl = new wxTextCtrl(panel, OPJENCO_PRECINCTSIZE, + wxGetApp().m_prsize, + wxDefaultPosition, wxSize(100, wxDefaultCoord), + wxTE_LEFT), + 0, wxALL | wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL, 3); + + codestreamSizer->Add(precinctSizer, 0, wxGROW | wxALL, 3); + + subtopSizer->Add(codestreamSizer, 0, wxGROW | wxALL, 3); + + // tile settings, column + wxStaticBox* tileBox = new wxStaticBox(panel, wxID_ANY, wxT("Tiles")); + wxBoxSizer* tileSizer = new wxStaticBoxSizer(tileBox, wxVERTICAL); + + // tile size sizer, row + wxBoxSizer* tilesizeSizer = new wxBoxSizer(wxHORIZONTAL); + + // add some text + tilesizeSizer->Add(new wxStaticText(panel, wxID_ANY, wxT("&Size:")), + 0, wxALL | wxALIGN_CENTER_VERTICAL, 3); + + // add some horizontal space + tilesizeSizer->Add(3, 3, 1, wxALL, 0); + + // add the value control + tilesizeSizer->Add( + m_tsizeCtrl = new wxTextCtrl(panel, OPJENCO_TILESIZE, + wxGetApp().m_tsize, + wxDefaultPosition, wxSize(80, wxDefaultCoord), + wxTE_LEFT), + 0, wxALL | wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL, 3); + + tileSizer->Add(tilesizeSizer, 0, wxGROW | wxALL, 3); + + // tile origin sizer, row + wxBoxSizer* tilorigSizer = new wxBoxSizer(wxHORIZONTAL); + + // add some text + tilorigSizer->Add(new wxStaticText(panel, wxID_ANY, wxT("&Origin:")), + 0, wxALL | wxALIGN_CENTER_VERTICAL, 3); + + // add some horizontal space + tilorigSizer->Add(3, 3, 1, wxALL, 0); + + // add the value control + tilorigSizer->Add( + m_toriginCtrl = new wxTextCtrl(panel, OPJENCO_TILORIG, + wxGetApp().m_torigin, + wxDefaultPosition, wxSize(80, wxDefaultCoord), + wxTE_LEFT), + 0, wxALL | wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL, 3); + + tileSizer->Add(tilorigSizer, 0, wxGROW | wxALL, 3); + + subtopSizer->Add(tileSizer, 0, wxGROW | wxALL, 3); + + // progression and profile settings, column + wxString choices[] = {wxT("LRCP"), wxT("RLCP"), wxT("RPCL"), wxT("PCRL"), wxT("CPRL"), + wxT("DCI2K24"), wxT("DCI2K48"), wxT("DCI4K")}; + progressionBox = new wxRadioBox(panel, OPJENCO_PROGRESSION, + wxT("Progression order/profile"), + wxDefaultPosition, wxDefaultSize, + WXSIZEOF(choices), + choices, + 3, + wxRA_SPECIFY_COLS); + progressionBox->SetSelection(wxGetApp().m_progression); + + subtopSizer->Add(progressionBox, 0, wxGROW | wxALL, 3); + + topSizer->Add(subtopSizer, 1, wxGROW | wxALIGN_CENTRE | wxALL, 5); + + // assign top and fit it + panel->SetSizer(topSizer); + topSizer->Fit(panel); + + return panel; +} + +wxPanel* OPJEncoderDialog::CreatePart1_2SettingsPage(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 + wxFlexGridSizer *subtopSizer = new wxFlexGridSizer(2, 3, 3); + + // resilience settings, column + wxStaticBox* resilBox = new wxStaticBox(panel, wxID_ANY, wxT("Error resilience")); + wxBoxSizer* resilSizer = new wxStaticBoxSizer(resilBox, wxVERTICAL); + + // resil2 sizer, row + wxBoxSizer* resil2Sizer = new wxBoxSizer(wxHORIZONTAL); + + // SOP check box + resil2Sizer->Add( + m_sopCheck = new wxCheckBox(panel, OPJENCO_ENABLESOP, wxT("SOP"), + wxDefaultPosition, wxDefaultSize), + 0, wxGROW | wxALL, 3); + m_sopCheck->SetValue(wxGetApp().m_enablesop); + + // EPH check box + resil2Sizer->Add( + m_ephCheck = new wxCheckBox(panel, OPJENCO_ENABLEEPH, wxT("EPH"), + wxDefaultPosition, wxDefaultSize), + 0, wxGROW | wxALL, 3); + m_ephCheck->SetValue(wxGetApp().m_enableeph); + + resilSizer->Add(resil2Sizer, 0, wxGROW | wxALL, 3); + + // separation + resilSizer->Add(new wxStaticLine(panel, wxID_ANY), 0, wxEXPAND | wxLEFT | wxRIGHT, 3); + + // resil3 sizer, row + wxFlexGridSizer* resil3Sizer = new wxFlexGridSizer(3, 3, 3); + + // BYPASS check box + resil3Sizer->Add( + m_enablebypassCheck = new wxCheckBox(panel, OPJENCO_ENABLEBYPASS, wxT("BYPASS"), + wxDefaultPosition, wxDefaultSize), + 0, wxGROW | wxALL, 3); + m_enablebypassCheck->SetValue(wxGetApp().m_enablebypass); + + // RESET check box + resil3Sizer->Add( + m_enableresetCheck = new wxCheckBox(panel, OPJENCO_ENABLERESET, wxT("RESET"), + wxDefaultPosition, wxDefaultSize), + 0, wxGROW | wxALL, 3); + m_enableresetCheck->SetValue(wxGetApp().m_enablereset); + + // RESTART check box + resil3Sizer->Add( + m_enablerestartCheck = new wxCheckBox(panel, OPJENCO_ENABLERESTART, wxT("RESTART"), + wxDefaultPosition, wxDefaultSize), + 0, wxGROW | wxALL, 3); + m_enablerestartCheck->SetValue(wxGetApp().m_enablerestart); + + // VSC check box + resil3Sizer->Add( + m_enablevscCheck = new wxCheckBox(panel, OPJENCO_ENABLEVSC, wxT("VSC"), + wxDefaultPosition, wxDefaultSize), + 0, wxGROW | wxALL, 3); + m_enablevscCheck->SetValue(wxGetApp().m_enablevsc); + + // ERTERM check box + resil3Sizer->Add( + m_enableertermCheck = new wxCheckBox(panel, OPJENCO_ENABLEERTERM, wxT("ERTERM"), + wxDefaultPosition, wxDefaultSize), + 0, wxGROW | wxALL, 3); + m_enableertermCheck->SetValue(wxGetApp().m_enableerterm); + + // SEGMARK check box + resil3Sizer->Add( + m_enablesegmarkCheck = new wxCheckBox(panel, OPJENCO_ENABLESEGMARK, wxT("SEGMARK"), + wxDefaultPosition, wxDefaultSize), + 0, wxGROW | wxALL, 3); + m_enablesegmarkCheck->SetValue(wxGetApp().m_enablesegmark); + + resilSizer->Add(resil3Sizer, 0, wxGROW | wxALL, 3); + + subtopSizer->Add(resilSizer, 0, wxGROW | wxALL, 3); + + // ROI settings, column + wxStaticBox* roiBox = new wxStaticBox(panel, wxID_ANY, wxT("Region Of Interest")); + wxBoxSizer* roiSizer = new wxStaticBoxSizer(roiBox, wxVERTICAL); + + // component number sizer, row + wxBoxSizer* roicompSizer = new wxBoxSizer(wxHORIZONTAL); + + // add some text + roicompSizer->Add(new wxStaticText(panel, wxID_ANY, wxT("&Component:")), + 0, wxALL | wxALIGN_CENTER_VERTICAL, 3); + + // add some horizontal space + roicompSizer->Add(3, 3, 1, wxALL, 0); + + // add the value control + roicompSizer->Add( + /*m_layerCtrl =*/ new wxSpinCtrl(panel, OPJENCO_ROICOMP, + wxT("0"), + wxDefaultPosition, wxSize(80, wxDefaultCoord), + wxSP_ARROW_KEYS, + 0, 256, 0), + 0, wxALL | wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL, 3); + + roiSizer->Add(roicompSizer, 0, wxGROW | wxALL, 3); + + // upshift sizer, row + wxBoxSizer* roishiftSizer = new wxBoxSizer(wxHORIZONTAL); + + // add some text + roishiftSizer->Add(new wxStaticText(panel, wxID_ANY, wxT("&Upshift:")), + 0, wxALL | wxALIGN_CENTER_VERTICAL, 3); + + // add some horizontal space + roishiftSizer->Add(3, 3, 1, wxALL, 0); + + // add the value control + roishiftSizer->Add( + /*m_layerCtrl =*/ new wxSpinCtrl(panel, OPJENCO_ROISHIFT, + wxT("0"), + wxDefaultPosition, wxSize(80, wxDefaultCoord), + wxSP_ARROW_KEYS, + 0, 37, 0), + 0, wxALL | wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL, 3); + + roiSizer->Add(roishiftSizer, 0, wxGROW | wxALL, 3); + + subtopSizer->Add(roiSizer, 0, wxGROW | wxALL, 3); + + // POC settings, column + wxStaticBox* pocBox = new wxStaticBox(panel, wxID_ANY, wxT("POC")); + wxBoxSizer* pocSizer = new wxStaticBoxSizer(pocBox, wxVERTICAL); + + // POC check box + pocSizer->Add( + m_enablepocCheck = new wxCheckBox(panel, OPJENCO_ENABLEPOC, wxT("Enabled (tn=rs,cs,le,re,ce,pr)"), + wxDefaultPosition, wxDefaultSize), + 0, wxGROW | wxALL, 3); + m_enablepocCheck->SetValue(wxGetApp().m_enablepoc); + + // POC sizer, row + wxBoxSizer* pocspecSizer = new wxBoxSizer(wxHORIZONTAL); + + // add some text + pocspecSizer->Add(new wxStaticText(panel, wxID_ANY, wxT("&Changes:")), + 0, wxALL | wxALIGN_TOP, 3); + + // add some horizontal space + pocspecSizer->Add(3, 3, 1, wxALL, 0); + + // add the value control + pocspecSizer->Add( + m_pocCtrl = new wxTextCtrl(panel, OPJENCO_POCSPEC, + wxGetApp().m_poc, + wxDefaultPosition, wxSize(140, 60), + wxTE_LEFT | wxTE_MULTILINE), + 0, wxALL | wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL, 3); + m_pocCtrl->Enable(wxGetApp().m_enablepoc); + + pocSizer->Add(pocspecSizer, 0, wxGROW | wxALL, 3); + + subtopSizer->Add(pocSizer, 0, wxGROW | wxALL, 3); + + // Comment settings, column + wxStaticBox* commentBox = new wxStaticBox(panel, wxID_ANY, wxT("Comment")); + wxBoxSizer* commentSizer = new wxStaticBoxSizer(commentBox, wxVERTICAL); + + // commenting check box + commentSizer->Add( + m_enablecommCheck = new wxCheckBox(panel, OPJENCO_ENABLECOMM, wxT("Enabled (empty to reset)"), + wxDefaultPosition, wxDefaultSize), + 0, wxGROW | wxALL, 3); + m_enablecommCheck->SetValue(wxGetApp().m_enablecomm); + + // add some horizontal space + commentSizer->Add(3, 3, 1, wxALL, 0); + + // add the value control + commentSizer->Add( + m_commentCtrl = new wxTextCtrl(panel, OPJENCO_COMMENTTEXT, + wxGetApp().m_comment, + wxDefaultPosition, wxSize(wxDefaultCoord, 60), + wxTE_LEFT | wxTE_MULTILINE), + 0, wxGROW | wxALL | wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL, 3); + m_commentCtrl->Enable(wxGetApp().m_enablecomm); + + subtopSizer->Add(commentSizer, 0, wxGROW | wxALL, 3); + + // Index file settings, column + wxStaticBox* indexBox = new wxStaticBox(panel, wxID_ANY, wxT("Indexing")); + wxBoxSizer* indexSizer = new wxStaticBoxSizer(indexBox, wxVERTICAL); + + // indexing check box + indexSizer->Add( + m_enableidxCheck = new wxCheckBox(panel, OPJENCO_ENABLEINDEX, wxT("Enabled"), + wxDefaultPosition, wxDefaultSize), + 0, wxGROW | wxALL, 3); + m_enableidxCheck->SetValue(wxGetApp().m_enableidx); + + // index file sizer, row + wxBoxSizer* indexnameSizer = new wxBoxSizer(wxHORIZONTAL); + + // add some text + indexnameSizer->Add(new wxStaticText(panel, wxID_ANY, wxT("&File name:")), + 0, wxALL | wxALIGN_CENTER_VERTICAL, 3); + + // add some horizontal space + indexnameSizer->Add(3, 3, 1, wxALL, 0); + + // add the value control + indexnameSizer->Add( + m_indexCtrl = new wxTextCtrl(panel, OPJENCO_INDEXNAME, + wxGetApp().m_index, + wxDefaultPosition, wxSize(120, wxDefaultCoord), + wxTE_LEFT), + 0, wxALL | wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL, 3); + m_indexCtrl->Enable(wxGetApp().m_enableidx); + + indexSizer->Add(indexnameSizer, 0, wxGROW | wxALL, 3); + + subtopSizer->Add(indexSizer, 0, wxGROW | wxALL, 3); + + topSizer->Add(subtopSizer, 1, wxGROW | wxALIGN_CENTRE | wxALL, 5); + + // assign top and fit it + panel->SetSizer(topSizer); + topSizer->Fit(panel); + + return panel; +} + +void OPJEncoderDialog::OnEnableComm(wxCommandEvent& event) +{ + if (event.IsChecked()) { + wxLogMessage(wxT("Comment enabled")); + m_commentCtrl->Enable(true); + } else { + wxLogMessage(wxT("Comment disabled")); + m_commentCtrl->Enable(false); + } + +} + +void OPJEncoderDialog::OnEnableIdx(wxCommandEvent& event) +{ + if (event.IsChecked()) { + wxLogMessage(wxT("Index enabled")); + m_indexCtrl->Enable(true); + } else { + wxLogMessage(wxT("Index disabled")); + m_indexCtrl->Enable(false); + } + +} + +void OPJEncoderDialog::OnEnablePoc(wxCommandEvent& event) +{ + if (event.IsChecked()) { + wxLogMessage(wxT("POC enabled")); + m_pocCtrl->Enable(true); + } else { + wxLogMessage(wxT("POC disabled")); + m_pocCtrl->Enable(false); + } + +} + +void OPJEncoderDialog::OnRadioQualityRate(wxCommandEvent& event) +{ + if (event.GetId() == OPJENCO_QUALITYRADIO) { + wxLogMessage(wxT("Quality selected")); + m_rateCtrl->Enable(false); + m_qualityCtrl->Enable(true); + } else { + wxLogMessage(wxT("Rate selected")); + m_rateCtrl->Enable(true); + m_qualityCtrl->Enable(false); + } +} + +#ifdef USE_JPWL +void OPJEncoderDialog::OnEnableJPWL(wxCommandEvent& event) +{ + int specno; + + if (event.IsChecked()) { + wxLogMessage(wxT("JPWL enabled")); + for (specno = 0; specno < MYJPWL_MAX_NO_TILESPECS; specno++) { + m_hprotChoice[specno]->Enable(true); + m_htileCtrl[specno]->Enable(true); + m_pprotChoice[specno]->Enable(true); + m_ptileCtrl[specno]->Enable(true); + m_ppackCtrl[specno]->Enable(true); + m_sensiChoice[specno]->Enable(true); + m_stileCtrl[specno]->Enable(true); + } + OnHprotSelect(event); + OnPprotSelect(event); + OnSensiSelect(event); + } else { + wxLogMessage(wxT("JPWL disabled")); + for (specno = 0; specno < MYJPWL_MAX_NO_TILESPECS; specno++) { + m_hprotChoice[specno]->Enable(false); + m_htileCtrl[specno]->Enable(false); + m_pprotChoice[specno]->Enable(false); + m_ptileCtrl[specno]->Enable(false); + m_ppackCtrl[specno]->Enable(false); + m_sensiChoice[specno]->Enable(false); + m_stileCtrl[specno]->Enable(false); + } + } + +} + +void OPJEncoderDialog::OnHprotSelect(wxCommandEvent& event) +{ + int specno; + + // deactivate properly + for (specno = MYJPWL_MAX_NO_TILESPECS - 1; specno >= 0; specno--) { + if (!m_hprotChoice[specno]->GetSelection()) { + m_hprotChoice[specno]->Enable(false); + m_htileCtrl[specno]->Enable(false); + } else + break; + } + if (specno < (MYJPWL_MAX_NO_TILESPECS - 1)) { + m_hprotChoice[specno + 1]->Enable(true); + m_htileCtrl[specno + 1]->Enable(true); + } + + //wxLogMessage(wxT("hprot changed: %d"), specno); +} + +void OPJEncoderDialog::OnPprotSelect(wxCommandEvent& event) +{ + int specno; + + // deactivate properly + for (specno = MYJPWL_MAX_NO_TILESPECS - 1; specno >= 0; specno--) { + if (!m_pprotChoice[specno]->GetSelection()) { + m_pprotChoice[specno]->Enable(false); + m_ptileCtrl[specno]->Enable(false); + m_ppackCtrl[specno]->Enable(false); + } else + break; + } + if (specno < (MYJPWL_MAX_NO_TILESPECS - 1)) { + m_pprotChoice[specno + 1]->Enable(true); + m_ptileCtrl[specno + 1]->Enable(true); + m_ppackCtrl[specno + 1]->Enable(true); + } + + //wxLogMessage(wxT("pprot changed: %d"), specno); +} + +void OPJEncoderDialog::OnSensiSelect(wxCommandEvent& event) +{ + int specno; + + // deactivate properly + for (specno = MYJPWL_MAX_NO_TILESPECS - 1; specno >= 0; specno--) { + if (!m_sensiChoice[specno]->GetSelection()) { + m_sensiChoice[specno]->Enable(false); + m_stileCtrl[specno]->Enable(false); + } else + break; + } + if (specno < (MYJPWL_MAX_NO_TILESPECS - 1)) { + m_sensiChoice[specno + 1]->Enable(true); + m_stileCtrl[specno + 1]->Enable(true); + } + + //wxLogMessage(wxT("sprot changed: %d"), specno); +} + + +#endif // USE_JPWL + diff --git a/applications/OPJViewer/source/OPJThreads.cpp b/applications/OPJViewer/source/OPJThreads.cpp index 3c93ee23..14159ac9 100644 --- a/applications/OPJViewer/source/OPJThreads.cpp +++ b/applications/OPJViewer/source/OPJThreads.cpp @@ -1,1268 +1,1268 @@ -/* - * Copyright (c) 2007, Digital Signal Processing Laboratory, Universita'  degli studi di Perugia (UPG), Italy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are 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. - */ -#include "OPJViewer.h" - - -///////////////////////////////////////////////////////////////////// -// Encoding thread class -///////////////////////////////////////////////////////////////////// - -OPJEncoThread::OPJEncoThread(OPJCanvas *canvas) - : wxThread() -{ - m_count = 0; - m_canvas = canvas; -} - -void OPJEncoThread::WriteText(const wxString& text) -{ - wxString msg; - - // before doing any GUI calls we must ensure that this thread is the only - // one doing it! - -#ifndef __WXGTK__ - wxMutexGuiEnter(); -#endif // __WXGTK__ - - msg << text; - m_canvas->WriteText(msg); - -#ifndef __WXGTK__ - wxMutexGuiLeave(); -#endif // __WXGTK__ -} - -void OPJEncoThread::OnExit() -{ - wxCriticalSectionLocker locker(wxGetApp().m_enco_critsect); - - wxArrayThread& ethreads = wxGetApp().m_enco_threads; - ethreads.Remove(this); - - if (ethreads.IsEmpty() ) - { - // signal the main thread that there are no more threads left if it is - // waiting for us - if (wxGetApp().m_enco_waitingUntilAllDone) { - wxGetApp().m_enco_waitingUntilAllDone = false; - wxGetApp().m_enco_semAllDone.Post(); - } - } -} - -void *OPJEncoThread::Entry() -{ - wxString text; - - 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("Enco thread %d started"), m_canvas->m_childframe->m_winnumber); - WriteText(text); - - // set handler properties - wxJPEG2000Handler *jpeg2000handler = (wxJPEG2000Handler *) wxImage::FindHandler(wxBITMAP_TYPE_JPEG2000); - jpeg2000handler->m_subsampling = wxGetApp().m_subsampling; - jpeg2000handler->m_origin = wxGetApp().m_origin; - jpeg2000handler->m_rates = wxGetApp().m_rates; - jpeg2000handler->m_quality = wxGetApp().m_quality; - jpeg2000handler->m_enablequality = wxGetApp().m_enablequality; - jpeg2000handler->m_multicomp = wxGetApp().m_multicomp; - jpeg2000handler->m_irreversible = wxGetApp().m_irreversible; - jpeg2000handler->m_resolutions = wxGetApp().m_resolutions; - jpeg2000handler->m_progression = wxGetApp().m_progression; - jpeg2000handler->m_cbsize = wxGetApp().m_cbsize; - jpeg2000handler->m_prsize = wxGetApp().m_prsize; - jpeg2000handler->m_tsize = wxGetApp().m_tsize; - jpeg2000handler->m_torigin = wxGetApp().m_torigin; - jpeg2000handler->m_enablesop = wxGetApp().m_enablesop; - jpeg2000handler->m_enableeph = wxGetApp().m_enableeph; - jpeg2000handler->m_enablebypass = wxGetApp().m_enablebypass; - jpeg2000handler->m_enablerestart = wxGetApp().m_enablerestart; - jpeg2000handler->m_enablereset = wxGetApp().m_enablereset; - jpeg2000handler->m_enablesegmark = wxGetApp().m_enablesegmark; - jpeg2000handler->m_enableerterm = wxGetApp().m_enableerterm; - jpeg2000handler->m_enablevsc = wxGetApp().m_enablevsc; - jpeg2000handler->m_enableidx = wxGetApp().m_enableidx; - jpeg2000handler->m_index = m_canvas->m_savename.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR) + wxGetApp().m_index; - jpeg2000handler->m_enablecomm = wxGetApp().m_enablecomm; - jpeg2000handler->m_comment = wxGetApp().m_comment; - jpeg2000handler->m_enablepoc = wxGetApp().m_enablepoc; - jpeg2000handler->m_poc = wxGetApp().m_poc; - - // save the file - if (!m_canvas->m_image100.SaveFile(m_canvas->m_savename.GetFullPath(), (wxBitmapType) wxBITMAP_TYPE_JPEG2000)) { - WriteText(wxT("Can't save image")); - return NULL; - } - - text.Printf(wxT("Enco thread %d finished"), m_canvas->m_childframe->m_winnumber); - WriteText(text); - return NULL; -} - - -///////////////////////////////////////////////////////////////////// -// Decoding thread class -///////////////////////////////////////////////////////////////////// -OPJDecoThread::OPJDecoThread(OPJCanvas *canvas) - : wxThread() -{ - m_count = 0; - m_canvas = canvas; -} - -void OPJDecoThread::WriteText(const wxString& text) -{ - wxString msg; - - // we use a fake event and post it for inter-thread gui communication - wxCommandEvent event(wxEVT_COMMAND_MENU_SELECTED, OPJFRAME_THREADLOGMSG); - event.SetInt(-1); - msg << text; - event.SetString(msg); - wxPostEvent(this->m_canvas->m_childframe->m_frame, event); - -/* - // before doing any GUI calls we must ensure that this thread is the only - // one doing it! - -#ifndef __WXGTK__ - wxMutexGuiEnter(); -#endif // __WXGTK__ - - msg << text; - m_canvas->WriteText(msg); - -#ifndef __WXGTK__ - wxMutexGuiLeave(); -#endif // __WXGTK__ -*/ -} - -void OPJDecoThread::OnExit() -{ - wxCriticalSectionLocker locker(wxGetApp().m_deco_critsect); - - wxArrayThread& dthreads = wxGetApp().m_deco_threads; - dthreads.Remove(this); - - if (dthreads.IsEmpty() ) - { - // signal the main thread that there are no more threads left if it is - // waiting for us - if (wxGetApp().m_deco_waitingUntilAllDone) { - wxGetApp().m_deco_waitingUntilAllDone = false; - wxGetApp().m_deco_semAllDone.Post(); - } - } -} - -void *OPJDecoThread::Entry() -{ - - wxString text; - - //srand(GetId()); - //int m_countnum = rand() % 9; - //text.Printf(wxT("Deco thread 0x%lx started (priority = %u, time = %d)."), - // GetId(), GetPriority(), m_countnum); - - // we have started - text.Printf(wxT("Deco thread %d started"), m_canvas->m_childframe->m_winnumber); - WriteText(text); - - // prepare dummy wximage - wxBitmap bitmap(100, 100); - wxImage image(100, 100, true); //= bitmap.ConvertToImage(); - image.Destroy(); - - // show image full name - WriteText(m_canvas->m_fname.GetFullPath()); - - // set handler properties - wxJPEG2000Handler *jpeg2000handler = (wxJPEG2000Handler *) wxImage::FindHandler(wxBITMAP_TYPE_JPEG2000); - jpeg2000handler->m_reducefactor = wxGetApp().m_reducefactor; - jpeg2000handler->m_qualitylayers = wxGetApp().m_qualitylayers; - jpeg2000handler->m_components = wxGetApp().m_components; - jpeg2000handler->m_framenum = wxGetApp().m_framenum; -#ifdef USE_JPWL - jpeg2000handler->m_enablejpwl = wxGetApp().m_enablejpwl; - jpeg2000handler->m_expcomps = wxGetApp().m_expcomps; - jpeg2000handler->m_maxtiles = wxGetApp().m_maxtiles; -#endif // USE_JPWL - -#ifdef USE_MXF - wxMXFHandler *mxfffhandler = (wxMXFHandler *) wxImage::FindHandler(wxBITMAP_TYPE_MXF); - mxfffhandler->m_reducefactor = wxGetApp().m_reducefactor; - mxfffhandler->m_qualitylayers = wxGetApp().m_qualitylayers; - mxfffhandler->m_components = wxGetApp().m_components; - mxfffhandler->m_framenum = wxGetApp().m_framenum; - mxfffhandler->m_filename = m_canvas->m_fname; -#ifdef USE_JPWL - mxfffhandler->m_enablejpwl = wxGetApp().m_enablejpwl; - mxfffhandler->m_expcomps = wxGetApp().m_expcomps; - mxfffhandler->m_maxtiles = wxGetApp().m_maxtiles; -#endif // USE_JPWL -#endif // USE_MXF - - // if decoding is enabled... - if (wxGetApp().m_enabledeco) { - - // load the file - if (!image.LoadFile(m_canvas->m_fname.GetFullPath(), wxBITMAP_TYPE_ANY, 0)) { - WriteText(wxT("Can't load image!")); - return NULL; - } - - } else { - - // display a warning - if (!image.Create(300, 5, false)) { - WriteText(wxT("Can't create image!")); - return NULL; - } - - } - - // assign 100% image - m_canvas->m_image100 = wxBitmap(image); - - // signal the frame to refresh the canvas - wxCommandEvent event(wxEVT_COMMAND_MENU_SELECTED, OPJFRAME_VIEWFIT); - event.SetString(wxT("Fit me")); - event.SetInt(m_canvas->m_childframe->m_winnumber); - wxPostEvent(m_canvas->m_childframe->m_frame, event); - - // 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 -#ifndef __WXGTK__ - //m_canvas->m_childframe->m_frame->Rescale(zooml, m_canvas->m_childframe); -#endif // __WXGTK__ - - //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); - return NULL; - -} - -///////////////////////////////////////////////////////////////////// -// Parsing thread class -///////////////////////////////////////////////////////////////////// - -OPJParseThread::OPJParseThread(OPJMarkerTree *tree, wxTreeItemId parentid) - : wxThread() -{ - m_count = 0; - m_tree = tree; - m_parentid = parentid; -} - -void OPJParseThread::WriteText(const wxString& text) -{ - wxString msg; - - // we use a fake event and post it for inter-thread gui communication - wxCommandEvent event(wxEVT_COMMAND_MENU_SELECTED, OPJFRAME_THREADLOGMSG); - event.SetInt(-1); - msg << text; - event.SetString(msg); - wxPostEvent(this->m_tree->m_childframe->m_frame, event); - -/* // before doing any GUI calls we must ensure that this thread is the only - // one doing it! - -#ifndef __WXGTK__ - wxMutexGuiEnter(); -#endif // __WXGTK - - msg << text; - m_tree->WriteText(msg); - -#ifndef __WXGTK__ - wxMutexGuiLeave(); -#endif // __WXGTK*/ -} - -void OPJParseThread::OnExit() -{ - wxCriticalSectionLocker locker(wxGetApp().m_parse_critsect); - - wxArrayThread& threads = wxGetApp().m_parse_threads; - threads.Remove(this); - - 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) { - wxGetApp().m_parse_waitingUntilAllDone = false; - wxGetApp().m_parse_semAllDone.Post(); - } - } -} - -void *OPJParseThread::Entry() -{ - - printf("Entering\n\n"); - - wxString text; - - srand(GetId()); - int m_countnum = rand() % 9; - text.Printf(wxT("Parse thread 0x%lx started (priority = %u, time = %d)."), - GetId(), GetPriority(), m_countnum); - WriteText(text); - LoadFile(m_tree->m_fname); - text.Printf(wxT("Parse thread 0x%lx finished."), GetId()); - WriteText(text); - - - //wxLogMessage(wxT("Entering\n")); //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] Parse thread 0x%lx here."), m_count, GetId()); - WriteText(text); - - // wxSleep() can't be called from non-GUI thread! - wxThread::Sleep(10); - }*/ - - // wxLogMessage(text); -- test wxLog thread safeness - - printf("Exiting\n\n"); - - return NULL; -} - - -/////////////////////////////////////////// -// Parsing hread and related -/////////////////////////////////////////// - -#if USE_GENERIC_TREECTRL -BEGIN_EVENT_TABLE(OPJMarkerTree, wxGenericTreeCtrl) -#else -BEGIN_EVENT_TABLE(OPJMarkerTree, wxTreeCtrl) -#endif - /*EVT_TREE_BEGIN_DRAG(TreeTest_Ctrl, OPJMarkerTree::OnBeginDrag) - EVT_TREE_BEGIN_RDRAG(TreeTest_Ctrl, OPJMarkerTree::OnBeginRDrag) - EVT_TREE_END_DRAG(TreeTest_Ctrl, OPJMarkerTree::OnEndDrag)*/ - /*EVT_TREE_BEGIN_LABEL_EDIT(TreeTest_Ctrl, OPJMarkerTree::OnBeginLabelEdit) - EVT_TREE_END_LABEL_EDIT(TreeTest_Ctrl, OPJMarkerTree::OnEndLabelEdit)*/ - /*EVT_TREE_DELETE_ITEM(TreeTest_Ctrl, OPJMarkerTree::OnDeleteItem)*/ -#if 0 // there are so many of those that logging them causes flicker - /*EVT_TREE_GET_INFO(TreeTest_Ctrl, OPJMarkerTree::OnGetInfo)*/ -#endif - /*EVT_TREE_SET_INFO(TreeTest_Ctrl, OPJMarkerTree::OnSetInfo) - EVT_TREE_ITEM_EXPANDED(TreeTest_Ctrl, OPJMarkerTree::OnItemExpanded)*/ - EVT_TREE_ITEM_EXPANDING(TreeTest_Ctrl, OPJMarkerTree::OnItemExpanding) - /*EVT_TREE_ITEM_COLLAPSED(TreeTest_Ctrl, OPJMarkerTree::OnItemCollapsed) - EVT_TREE_ITEM_COLLAPSING(TreeTest_Ctrl, OPJMarkerTree::OnItemCollapsing)*/ - - EVT_TREE_SEL_CHANGED(TreeTest_Ctrl, OPJMarkerTree::OnSelChanged) - /*EVT_TREE_SEL_CHANGING(TreeTest_Ctrl, OPJMarkerTree::OnSelChanging)*/ - /*EVT_TREE_KEY_DOWN(TreeTest_Ctrl, OPJMarkerTree::OnTreeKeyDown)*/ - /*EVT_TREE_ITEM_ACTIVATED(TreeTest_Ctrl, OPJMarkerTree::OnItemActivated)*/ - - // so many differents ways to handle right mouse button clicks... - /*EVT_CONTEXT_MENU(OPJMarkerTree::OnContextMenu)*/ - // 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_RIGHT_CLICK(TreeTest_Ctrl, OPJMarkerTree::OnItemRClick)*/ - - /*EVT_RIGHT_DOWN(OPJMarkerTree::OnRMouseDown) - EVT_RIGHT_UP(OPJMarkerTree::OnRMouseUp) - EVT_RIGHT_DCLICK(OPJMarkerTree::OnRMouseDClick)*/ -END_EVENT_TABLE() - -// OPJMarkerTree implementation -#if USE_GENERIC_TREECTRL -IMPLEMENT_DYNAMIC_CLASS(OPJMarkerTree, wxGenericTreeCtrl) -#else -IMPLEMENT_DYNAMIC_CLASS(OPJMarkerTree, wxTreeCtrl) -#endif - -OPJMarkerTree::OPJMarkerTree(wxWindow *parent, OPJChildFrame *subframe, wxFileName fname, wxString name, const wxWindowID id, - const wxPoint& pos, const wxSize& size, long style) - : wxTreeCtrl(parent, id, pos, size, style) -{ - m_reverseSort = false; - m_fname = fname; - - m_peektextCtrl = ((OPJFrame *) (parent->GetParent()->GetParent()))->m_textCtrlbrowse; - CreateImageList(); - - // Add some items to the tree - //AddTestItemsToTree(5, 5); - int image = wxGetApp().ShowImages() ? OPJMarkerTree::TreeCtrlIcon_Folder : -1; - wxTreeItemId rootId = AddRoot(name, - image, image, - new OPJMarkerData(name)); - - OPJParseThread *pthread = CreateParseThread(0x00, subframe); - if (pthread->Run() != wxTHREAD_NO_ERROR) - wxLogMessage(wxT("Can't start parse thread!")); - else - wxLogMessage(wxT("New parse thread started.")); - - m_childframe = subframe; -} - -void OPJMarkerTree::CreateImageList(int size) -{ - if (size == -1) { - SetImageList(NULL); - return; - } - if (size == 0) - size = m_imageSize; - else - m_imageSize = size; - - // Make an image list containing small icons - wxImageList *images = new wxImageList(size, size, true); - - // should correspond to TreeCtrlIcon_xxx enum - wxBusyCursor wait; - wxIcon icons[5]; - icons[0] = wxIcon(icon1_xpm); - icons[1] = wxIcon(icon2_xpm); - icons[2] = wxIcon(icon3_xpm); - icons[3] = wxIcon(icon4_xpm); - icons[4] = wxIcon(icon5_xpm); - - int sizeOrig = icons[0].GetWidth(); - for (size_t i = 0; i < WXSIZEOF(icons); i++) { - if (size == sizeOrig) { - images->Add(icons[i]); - } else { - images->Add(wxBitmap(wxBitmap(icons[i]).ConvertToImage().Rescale(size, size))); - } - } - - AssignImageList(images); -} - -#if USE_GENERIC_TREECTRL || !defined(__WXMSW__) -void OPJMarkerTree::CreateButtonsImageList(int size) -{ - if ( size == -1 ) { - SetButtonsImageList(NULL); - return; - } - - // Make an image list containing small icons - wxImageList *images = new wxImageList(size, size, true); - - // should correspond to TreeCtrlIcon_xxx enum - wxBusyCursor wait; - wxIcon icons[4]; - icons[0] = wxIcon(icon3_xpm); // closed - icons[1] = wxIcon(icon3_xpm); // closed, selected - icons[2] = wxIcon(icon5_xpm); // open - icons[3] = wxIcon(icon5_xpm); // open, selected - - for ( size_t i = 0; i < WXSIZEOF(icons); i++ ) { - int sizeOrig = icons[i].GetWidth(); - if ( size == sizeOrig ) { - images->Add(icons[i]); - } else { - images->Add(wxBitmap(wxBitmap(icons[i]).ConvertToImage().Rescale(size, size))); - } - } - - AssignButtonsImageList(images); -#else -void OPJMarkerTree::CreateButtonsImageList(int WXUNUSED(size)) -{ -#endif -} - -void OPJParseThread::LoadFile(wxFileName fname) -{ - wxTreeItemId rootid; - - // this is the root node - int image = wxGetApp().ShowImages() ? m_tree->TreeCtrlIcon_Folder : -1; - - if (this->m_parentid) { - // leaf of a tree - rootid = m_parentid; - m_tree->SetItemText(rootid, wxT("Parsing...")); - - } else { - - // delete the existing tree hierarchy - m_tree->DeleteAllItems(); - - // new tree - rootid = m_tree->AddRoot(wxT("Parsing..."), - image, - image, - new OPJMarkerData(fname.GetFullPath()) - ); - //m_tree->SetItemFont(rootid, *wxITALIC_FONT); - m_tree->SetItemBold(rootid); - } - - // open the file - wxFile m_file(fname.GetFullPath().c_str(), wxFile::read); - - // parsing enabled? - if (wxGetApp().m_enableparse) { - - // what is the extension? - if ((fname.GetExt() == wxT("j2k")) || (fname.GetExt() == wxT("j2c"))) { - - // parse the file - ParseJ2KFile(&m_file, 0, m_file.Length(), rootid); - - } else if ((fname.GetExt() == wxT("jp2")) || (fname.GetExt() == wxT("mj2"))) { - - // parse the file - if (this->m_parentid) { - //WriteText(wxT("Only a subsection of jp2")); - OPJMarkerData *data = (OPJMarkerData *) m_tree->GetItemData(rootid); - ParseJ2KFile(&m_file, data->m_start, data->m_length, rootid); - m_tree->Expand(rootid); - - } else { - // as usual - ParseJP2File(&m_file, 0, m_file.Length(), rootid); - } - - } else { - - // unknown extension - WriteText(wxT("Unknown file format!")); - - } - - } - - // this is the root node - if (this->m_parentid) - m_tree->SetItemText(rootid, wxT("Codestream")); - else - //m_tree->SetItemText(rootid, wxString::Format(wxT("%s (%d B)"), fname.GetFullName(), m_file.Length())); - m_tree->SetItemText(rootid, fname.GetFullName()); - - // close the file - m_file.Close(); - - WriteText(wxT("Parsing finished!")); -} - -/*int OPJMarkerTree::OnCompareItems(const wxTreeItemId& item1, - const wxTreeItemId& item2) -{ - if ( m_reverseSort ) - { - // just exchange 1st and 2nd items - return wxTreeCtrl::OnCompareItems(item2, item1); - } - else - { - return wxTreeCtrl::OnCompareItems(item1, item2); - } -}*/ - -/*void OPJMarkerTree::AddItemsRecursively(const wxTreeItemId& idParent, - size_t numChildren, - size_t depth, - size_t folder) -{ - if ( depth > 0 ) - { - bool hasChildren = depth > 1; - - wxString str; - for ( size_t n = 0; n < numChildren; n++ ) - { - // at depth 1 elements won't have any more children - if ( hasChildren ) - str.Printf(wxT("%s child %u"), wxT("Folder"), unsigned(n + 1)); - else - str.Printf(wxT("%s child %u.%u"), wxT("File"), unsigned(folder), unsigned(n + 1)); - - // here we pass to AppendItem() normal and selected item images (we - // suppose that selected image follows the normal one in the enum) - int image, imageSel; - if ( wxGetApp().ShowImages() ) - { - image = depth == 1 ? TreeCtrlIcon_File : TreeCtrlIcon_Folder; - imageSel = image + 1; - } - else - { - image = imageSel = -1; - } - wxTreeItemId id = AppendItem(idParent, str, image, imageSel, - new OPJMarkerData(str)); - - // and now we also set the expanded one (only for the folders) - if ( hasChildren && wxGetApp().ShowImages() ) - { - SetItemImage(id, TreeCtrlIcon_FolderOpened, - wxTreeItemIcon_Expanded); - } - - // remember the last child for OnEnsureVisible() - if ( !hasChildren && n == numChildren - 1 ) - { - m_lastItem = id; - } - - AddItemsRecursively(id, numChildren, depth - 1, n + 1); - } - } - //else: done! -}*/ - -/*void OPJMarkerTree::AddTestItemsToTree(size_t numChildren, - size_t depth) -{ - int image = wxGetApp().ShowImages() ? OPJMarkerTree::TreeCtrlIcon_Folder : -1; - wxTreeItemId rootId = AddRoot(wxT("Root"), - image, image, - new OPJMarkerData(wxT("Root item"))); - if ( image != -1 ) - { - SetItemImage(rootId, TreeCtrlIcon_FolderOpened, wxTreeItemIcon_Expanded); - } - - AddItemsRecursively(rootId, numChildren, depth, 0); - - // set some colours/fonts for testing - SetItemFont(rootId, *wxITALIC_FONT); - - wxTreeItemIdValue cookie; - wxTreeItemId id = GetFirstChild(rootId, cookie); - SetItemTextColour(id, *wxBLUE); - - id = GetNextChild(rootId, cookie); - id = GetNextChild(rootId, cookie); - SetItemTextColour(id, *wxRED); - SetItemBackgroundColour(id, *wxLIGHT_GREY); -}*/ - -/*void OPJMarkerTree::GetItemsRecursively(const wxTreeItemId& idParent, - wxTreeItemIdValue cookie) -{ - wxTreeItemId id; - - if ( !cookie ) - id = GetFirstChild(idParent, cookie); - else - id = GetNextChild(idParent, cookie); - - if ( !id.IsOk() ) - return; - - wxString text = GetItemText(id); - wxLogMessage(text); - - if (ItemHasChildren(id)) - GetItemsRecursively(id); - - GetItemsRecursively(idParent, cookie); -}*/ - -/*void OPJMarkerTree::DoToggleIcon(const wxTreeItemId& item) -{ - int image = (GetItemImage(item) == TreeCtrlIcon_Folder) - ? TreeCtrlIcon_File - : TreeCtrlIcon_Folder; - SetItemImage(item, image, wxTreeItemIcon_Normal); - - image = (GetItemImage(item) == TreeCtrlIcon_FolderSelected) - ? TreeCtrlIcon_FileSelected - : TreeCtrlIcon_FolderSelected; - SetItemImage(item, image, wxTreeItemIcon_Selected); -}*/ - -void OPJMarkerTree::LogEvent(const wxChar *name, const wxTreeEvent& event) -{ - wxTreeItemId item = event.GetItem(); - wxString text; - if ( item.IsOk() ) - text << wxT('"') << GetItemText(item).c_str() << wxT('"'); - else - text = wxT("invalid item"); - wxLogMessage(wxT("%s(%s)"), name, text.c_str()); -} - -OPJParseThread *OPJMarkerTree::CreateParseThread(wxTreeItemId parentid, OPJChildFrame *subframe) -{ - OPJParseThread *pthread = new OPJParseThread(this, parentid); - - if (pthread->Create() != wxTHREAD_NO_ERROR) - wxLogError(wxT("Can't create parse thread!")); - - wxCriticalSectionLocker enter(wxGetApp().m_parse_critsect); - wxGetApp().m_parse_threads.Add(pthread); - - return pthread; -} - - -/*// avoid repetition -#define TREE_EVENT_HANDLER(name) \ -void OPJMarkerTree::name(wxTreeEvent& event) \ -{ \ - LogEvent(_T(#name), event); \ - SetLastItem(wxTreeItemId()); \ - event.Skip(); \ -}*/ - -/*TREE_EVENT_HANDLER(OnBeginRDrag)*/ -/*TREE_EVENT_HANDLER(OnDeleteItem)*/ -/*TREE_EVENT_HANDLER(OnGetInfo) -TREE_EVENT_HANDLER(OnSetInfo)*/ -/*TREE_EVENT_HANDLER(OnItemExpanded) -TREE_EVENT_HANDLER(OnItemExpanding)*/ -/*TREE_EVENT_HANDLER(OnItemCollapsed)*/ -/*TREE_EVENT_HANDLER(OnSelChanged) -TREE_EVENT_HANDLER(OnSelChanging)*/ - -/*#undef TREE_EVENT_HANDLER*/ - -void OPJMarkerTree::OnItemExpanding(wxTreeEvent& event) -{ - wxTreeItemId item = event.GetItem(); - OPJMarkerData* data = (OPJMarkerData *) GetItemData(item); - wxString text; - - if (item.IsOk()) - text << wxT('"') << GetItemText(item).c_str() << wxT('"'); - else - text = wxT("invalid item"); - - if (wxStrcmp(data->GetDesc1(), wxT("INFO-CSTREAM"))) - return; - - wxLogMessage(wxT("Expanding... (%s -> %s, %s, %d, %d)"), - text.c_str(), data->GetDesc1(), data->GetDesc2(), - data->m_start, data->m_length); - - // the codestream box is being asked for expansion - wxTreeItemIdValue cookie; - if (!GetFirstChild(item, cookie).IsOk()) { - OPJParseThread *pthread = CreateParseThread(item); - if (pthread->Run() != wxTHREAD_NO_ERROR) - wxLogMessage(wxT("Can't start parse thread!")); - else - wxLogMessage(wxT("New parse thread started.")); - } -} - -void OPJMarkerTree::OnSelChanged(wxTreeEvent& event) -{ - int bunch_linesize = 16; - int bunch_numlines = 7; - - wxTreeItemId item = event.GetItem(); - OPJMarkerData* data = (OPJMarkerData *) GetItemData(item); - wxString text; - int l, c, pos = 0, pre_pos; - - m_peektextCtrl->Clear(); - - /*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");*/ - - // open the file and browse a little - wxFile *fp = new wxFile(m_fname.GetFullPath().c_str(), wxFile::read); - - // go to position claimed - fp->Seek(data->m_start, wxFromStart); - - // read a bunch - int max_read = wxMin(wxFileOffset(bunch_linesize * bunch_numlines), data->m_length - data->m_start + 1); - if (data->m_desc == wxT("MARK (65380)")) { - /*wxLogMessage(data->m_desc);*/ - max_read = data->m_length - data->m_start + 1; - bunch_numlines = (int) ceil((float) max_read / (float) bunch_linesize); - } - unsigned char *buffer = new unsigned char[bunch_linesize * bunch_numlines]; - 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("%010d:"), data->m_start + pos); - - pre_pos = pos; - - // add hex browsing text - for (c = 0; c < bunch_linesize; c++) { - - if (!(c % 8)) - text << wxT(" "); - - if (pos < max_read) { - text << wxString::Format(wxT("%02X "), buffer[pos]); - } else - text << wxT(" "); - pos++; - } - - text << wxT(" "); - - // add char browsing text - for (c = 0; c < bunch_linesize; c++) { - - if (pre_pos < max_read) { - 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::FromAscii((char) buffer[pre_pos]) << wxT("."); - } else - text << wxT(" "); - pre_pos++; - } - - text << wxT("\n"); - - } - - // close the file - fp->Close(); - - m_peektextCtrl->WriteText(text); - - delete buffer; -} - -/*void LogKeyEvent(const wxChar *name, const wxKeyEvent& event) -{ - wxString key; - long keycode = event.GetKeyCode(); - { - switch ( keycode ) - { - case WXK_BACK: key = wxT("BACK"); break; - case WXK_TAB: key = wxT("TAB"); break; - case WXK_RETURN: key = wxT("RETURN"); break; - case WXK_ESCAPE: key = wxT("ESCAPE"); break; - case WXK_SPACE: key = wxT("SPACE"); break; - case WXK_DELETE: key = wxT("DELETE"); break; - case WXK_START: key = wxT("START"); break; - case WXK_LBUTTON: key = wxT("LBUTTON"); break; - case WXK_RBUTTON: key = wxT("RBUTTON"); break; - case WXK_CANCEL: key = wxT("CANCEL"); break; - case WXK_MBUTTON: key = wxT("MBUTTON"); break; - case WXK_CLEAR: key = wxT("CLEAR"); break; - case WXK_SHIFT: key = wxT("SHIFT"); break; - case WXK_ALT: key = wxT("ALT"); break; - case WXK_CONTROL: key = wxT("CONTROL"); break; - case WXK_MENU: key = wxT("MENU"); break; - case WXK_PAUSE: key = wxT("PAUSE"); break; - case WXK_CAPITAL: key = wxT("CAPITAL"); break; - case WXK_END: key = wxT("END"); break; - case WXK_HOME: key = wxT("HOME"); break; - case WXK_LEFT: key = wxT("LEFT"); break; - case WXK_UP: key = wxT("UP"); break; - case WXK_RIGHT: key = wxT("RIGHT"); break; - case WXK_DOWN: key = wxT("DOWN"); break; - case WXK_SELECT: key = wxT("SELECT"); break; - case WXK_PRINT: key = wxT("PRINT"); break; - case WXK_EXECUTE: key = wxT("EXECUTE"); break; - case WXK_SNAPSHOT: key = wxT("SNAPSHOT"); break; - case WXK_INSERT: key = wxT("INSERT"); break; - case WXK_HELP: key = wxT("HELP"); break; - case WXK_NUMPAD0: key = wxT("NUMPAD0"); break; - case WXK_NUMPAD1: key = wxT("NUMPAD1"); break; - case WXK_NUMPAD2: key = wxT("NUMPAD2"); break; - case WXK_NUMPAD3: key = wxT("NUMPAD3"); break; - case WXK_NUMPAD4: key = wxT("NUMPAD4"); break; - case WXK_NUMPAD5: key = wxT("NUMPAD5"); break; - case WXK_NUMPAD6: key = wxT("NUMPAD6"); break; - case WXK_NUMPAD7: key = wxT("NUMPAD7"); break; - case WXK_NUMPAD8: key = wxT("NUMPAD8"); break; - case WXK_NUMPAD9: key = wxT("NUMPAD9"); break; - case WXK_MULTIPLY: key = wxT("MULTIPLY"); break; - case WXK_ADD: key = wxT("ADD"); break; - case WXK_SEPARATOR: key = wxT("SEPARATOR"); break; - case WXK_SUBTRACT: key = wxT("SUBTRACT"); break; - case WXK_DECIMAL: key = wxT("DECIMAL"); break; - case WXK_DIVIDE: key = wxT("DIVIDE"); break; - case WXK_F1: key = wxT("F1"); break; - case WXK_F2: key = wxT("F2"); break; - case WXK_F3: key = wxT("F3"); break; - case WXK_F4: key = wxT("F4"); break; - case WXK_F5: key = wxT("F5"); break; - case WXK_F6: key = wxT("F6"); break; - case WXK_F7: key = wxT("F7"); break; - case WXK_F8: key = wxT("F8"); break; - case WXK_F9: key = wxT("F9"); break; - case WXK_F10: key = wxT("F10"); break; - case WXK_F11: key = wxT("F11"); break; - case WXK_F12: key = wxT("F12"); break; - case WXK_F13: key = wxT("F13"); break; - case WXK_F14: key = wxT("F14"); break; - case WXK_F15: key = wxT("F15"); break; - case WXK_F16: key = wxT("F16"); break; - case WXK_F17: key = wxT("F17"); break; - case WXK_F18: key = wxT("F18"); break; - case WXK_F19: key = wxT("F19"); break; - case WXK_F20: key = wxT("F20"); break; - case WXK_F21: key = wxT("F21"); break; - case WXK_F22: key = wxT("F22"); break; - case WXK_F23: key = wxT("F23"); break; - case WXK_F24: key = wxT("F24"); break; - case WXK_NUMLOCK: key = wxT("NUMLOCK"); break; - case WXK_SCROLL: key = wxT("SCROLL"); break; - case WXK_PAGEUP: key = wxT("PAGEUP"); break; - case WXK_PAGEDOWN: key = wxT("PAGEDOWN"); break; - case WXK_NUMPAD_SPACE: key = wxT("NUMPAD_SPACE"); break; - case WXK_NUMPAD_TAB: key = wxT("NUMPAD_TAB"); break; - case WXK_NUMPAD_ENTER: key = wxT("NUMPAD_ENTER"); break; - case WXK_NUMPAD_F1: key = wxT("NUMPAD_F1"); break; - case WXK_NUMPAD_F2: key = wxT("NUMPAD_F2"); break; - case WXK_NUMPAD_F3: key = wxT("NUMPAD_F3"); break; - case WXK_NUMPAD_F4: key = wxT("NUMPAD_F4"); break; - case WXK_NUMPAD_HOME: key = wxT("NUMPAD_HOME"); break; - case WXK_NUMPAD_LEFT: key = wxT("NUMPAD_LEFT"); break; - case WXK_NUMPAD_UP: key = wxT("NUMPAD_UP"); break; - case WXK_NUMPAD_RIGHT: key = wxT("NUMPAD_RIGHT"); break; - case WXK_NUMPAD_DOWN: key = wxT("NUMPAD_DOWN"); break; - case WXK_NUMPAD_PAGEUP: key = wxT("NUMPAD_PAGEUP"); break; - case WXK_NUMPAD_PAGEDOWN: key = wxT("NUMPAD_PAGEDOWN"); break; - case WXK_NUMPAD_END: key = wxT("NUMPAD_END"); break; - case WXK_NUMPAD_BEGIN: key = wxT("NUMPAD_BEGIN"); break; - case WXK_NUMPAD_INSERT: key = wxT("NUMPAD_INSERT"); break; - case WXK_NUMPAD_DELETE: key = wxT("NUMPAD_DELETE"); break; - case WXK_NUMPAD_EQUAL: key = wxT("NUMPAD_EQUAL"); break; - case WXK_NUMPAD_MULTIPLY: key = wxT("NUMPAD_MULTIPLY"); break; - case WXK_NUMPAD_ADD: key = wxT("NUMPAD_ADD"); break; - case WXK_NUMPAD_SEPARATOR: key = wxT("NUMPAD_SEPARATOR"); break; - case WXK_NUMPAD_SUBTRACT: key = wxT("NUMPAD_SUBTRACT"); break; - case WXK_NUMPAD_DECIMAL: key = wxT("NUMPAD_DECIMAL"); break; - - default: - { - if ( keycode < 128 && wxIsprint((int)keycode) ) - key.Printf(wxT("'%c'"), (char)keycode); - else if ( keycode > 0 && keycode < 27 ) - key.Printf(_("Ctrl-%c"), wxT('A') + keycode - 1); - else - key.Printf(wxT("unknown (%ld)"), keycode); - } - } - } - - wxLogMessage(wxT("%s event: %s (flags = %c%c%c%c)"), - name, - key.c_str(), - event.ControlDown() ? wxT('C') : wxT('-'), - event.AltDown() ? wxT('A') : wxT('-'), - event.ShiftDown() ? wxT('S') : wxT('-'), - event.MetaDown() ? wxT('M') : wxT('-')); -} - -void OPJMarkerTree::OnTreeKeyDown(wxTreeEvent& event) -{ - LogKeyEvent(wxT("Tree key down "), event.GetKeyEvent()); - - event.Skip(); -}*/ - -/*void OPJMarkerTree::OnBeginDrag(wxTreeEvent& event) -{ - // need to explicitly allow drag - if ( event.GetItem() != GetRootItem() ) - { - m_draggedItem = event.GetItem(); - - wxLogMessage(wxT("OnBeginDrag: started dragging %s"), - GetItemText(m_draggedItem).c_str()); - - event.Allow(); - } - else - { - wxLogMessage(wxT("OnBeginDrag: this item can't be dragged.")); - } -} - -void OPJMarkerTree::OnEndDrag(wxTreeEvent& event) -{ - wxTreeItemId itemSrc = m_draggedItem, - itemDst = event.GetItem(); - m_draggedItem = (wxTreeItemId)0l; - - // where to copy the item? - if ( itemDst.IsOk() && !ItemHasChildren(itemDst) ) - { - // copy to the parent then - itemDst = GetItemParent(itemDst); - } - - if ( !itemDst.IsOk() ) - { - wxLogMessage(wxT("OnEndDrag: can't drop here.")); - - return; - } - - wxString text = GetItemText(itemSrc); - wxLogMessage(wxT("OnEndDrag: '%s' copied to '%s'."), - text.c_str(), GetItemText(itemDst).c_str()); - - // just do append here - we could also insert it just before/after the item - // on which it was dropped, but this requires slightly more work... we also - // completely ignore the client data and icon of the old item but could - // copy them as well. - // - // Finally, we only copy one item here but we might copy the entire tree if - // we were dragging a folder. - int image = wxGetApp().ShowImages() ? TreeCtrlIcon_File : -1; - AppendItem(itemDst, text, image); -}*/ - -/*void OPJMarkerTree::OnBeginLabelEdit(wxTreeEvent& event) -{ - wxLogMessage(wxT("OnBeginLabelEdit")); - - // for testing, prevent this item's label editing - wxTreeItemId itemId = event.GetItem(); - if ( IsTestItem(itemId) ) - { - wxMessageBox(wxT("You can't edit this item.")); - - event.Veto(); - } - else if ( itemId == GetRootItem() ) - { - // test that it is possible to change the text of the item being edited - SetItemText(itemId, _T("Editing root item")); - } -} - -void OPJMarkerTree::OnEndLabelEdit(wxTreeEvent& event) -{ - wxLogMessage(wxT("OnEndLabelEdit")); - - // don't allow anything except letters in the labels - if ( !event.GetLabel().IsWord() ) - { - wxMessageBox(wxT("The new label should be a single word.")); - - event.Veto(); - } -}*/ - -/*void OPJMarkerTree::OnItemCollapsing(wxTreeEvent& event) -{ - wxLogMessage(wxT("OnItemCollapsing")); - - // for testing, prevent the user from collapsing the first child folder - wxTreeItemId itemId = event.GetItem(); - if ( IsTestItem(itemId) ) - { - wxMessageBox(wxT("You can't collapse this item.")); - - event.Veto(); - } -}*/ - -/*void OPJMarkerTree::OnItemActivated(wxTreeEvent& event) -{ - // show some info about this item - wxTreeItemId itemId = event.GetItem(); - OPJMarkerData *item = (OPJMarkerData *)GetItemData(itemId); - - if ( item != NULL ) - { - item->ShowInfo(this); - } - - wxLogMessage(wxT("OnItemActivated")); -}*/ - -void OPJMarkerTree::OnItemMenu(wxTreeEvent& event) -{ - /*wxTreeItemId itemId = event.GetItem(); - OPJMarkerData *item = itemId.IsOk() ? (OPJMarkerData *)GetItemData(itemId) - : NULL; - - wxLogMessage(wxT("OnItemMenu for item \"%s\""), item ? item->GetDesc() - : _T(""));*/ - - //wxLogMessage(wxT("EEEEEEEEEE")); - - //event.Skip(); -} - -/*void OPJMarkerTree::OnContextMenu(wxContextMenuEvent& event) -{ - wxPoint pt = event.GetPosition(); - wxTreeItemId item; - wxLogMessage(wxT("OnContextMenu at screen coords (%i, %i)"), pt.x, pt.y); - - // check if event was generated by keyboard (MSW-specific?) - if ( pt.x == -1 && pt.y == -1 ) //(this is how MSW indicates it) - { - if ( !HasFlag(wxTR_MULTIPLE) ) - item = GetSelection(); - - // attempt to guess where to show the menu - if ( item.IsOk() ) - { - // if an item was clicked, show menu to the right of it - wxRect rect; - GetBoundingRect(item, rect, true );// only the label - pt = wxPoint(rect.GetRight(), rect.GetTop()); - } - else - { - pt = wxPoint(0, 0); - } - } - else // event was generated by mouse, use supplied coords - { - pt = ScreenToClient(pt); - item = HitTest(pt); - } - - ShowMenu(item, pt); -}*/ - -/*void OPJMarkerTree::ShowMenu(wxTreeItemId id, const wxPoint& pt) -{ - wxString title; - if ( id.IsOk() ) - { - title << wxT("Menu for ") << GetItemText(id); - } - else - { - title = wxT("Menu for no particular item"); - } - -#if wxUSE_MENUS - wxMenu menu(title); - menu.Append(TreeTest_About, wxT("&About...")); - menu.AppendSeparator(); - menu.Append(TreeTest_Highlight, wxT("&Highlight item")); - menu.Append(TreeTest_Dump, wxT("&Dump")); - - PopupMenu(&menu, pt); -#endif // wxUSE_MENUS -}*/ - -/*void OPJMarkerTree::OnItemRClick(wxTreeEvent& event) -{ - wxTreeItemId itemId = event.GetItem(); - OPJMarkerData *item = itemId.IsOk() ? (OPJMarkerData *)GetItemData(itemId) - : NULL; - - wxLogMessage(wxT("Item \"%s\" right clicked"), item ? item->GetDesc() - : _T("")); - - event.Skip(); -}*/ - -/* -void OPJMarkerTree::OnRMouseDown(wxMouseEvent& event) -{ - wxLogMessage(wxT("Right mouse button down")); - - event.Skip(); -} - -void OPJMarkerTree::OnRMouseUp(wxMouseEvent& event) -{ - wxLogMessage(wxT("Right mouse button up")); - - event.Skip(); -} - -void OPJMarkerTree::OnRMouseDClick(wxMouseEvent& event) -{ - wxTreeItemId id = HitTest(event.GetPosition()); - if ( !id ) - wxLogMessage(wxT("No item under mouse")); - else - { - OPJMarkerData *item = (OPJMarkerData *)GetItemData(id); - if ( item ) - wxLogMessage(wxT("Item '%s' under mouse"), item->GetDesc()); - } - - event.Skip(); -} -*/ - -static inline const wxChar *Bool2String(bool b) -{ - return b ? wxT("") : wxT("not "); -} - -void OPJMarkerData::ShowInfo(wxTreeCtrl *tree) -{ - wxLogMessage(wxT("Item '%s': %sselected, %sexpanded, %sbold,\n") - wxT("%u children (%u immediately under this item)."), - m_desc.c_str(), - Bool2String(tree->IsSelected(GetId())), - Bool2String(tree->IsExpanded(GetId())), - Bool2String(tree->IsBold(GetId())), - unsigned(tree->GetChildrenCount(GetId())), - unsigned(tree->GetChildrenCount(GetId(), false))); -} - - +/* + * Copyright (c) 2007, Digital Signal Processing Laboratory, Universita'  degli studi di Perugia (UPG), Italy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are 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. + */ +#include "OPJViewer.h" + + +///////////////////////////////////////////////////////////////////// +// Encoding thread class +///////////////////////////////////////////////////////////////////// + +OPJEncoThread::OPJEncoThread(OPJCanvas *canvas) + : wxThread() +{ + m_count = 0; + m_canvas = canvas; +} + +void OPJEncoThread::WriteText(const wxString& text) +{ + wxString msg; + + // before doing any GUI calls we must ensure that this thread is the only + // one doing it! + +#ifndef __WXGTK__ + wxMutexGuiEnter(); +#endif // __WXGTK__ + + msg << text; + m_canvas->WriteText(msg); + +#ifndef __WXGTK__ + wxMutexGuiLeave(); +#endif // __WXGTK__ +} + +void OPJEncoThread::OnExit() +{ + wxCriticalSectionLocker locker(wxGetApp().m_enco_critsect); + + wxArrayThread& ethreads = wxGetApp().m_enco_threads; + ethreads.Remove(this); + + if (ethreads.IsEmpty() ) + { + // signal the main thread that there are no more threads left if it is + // waiting for us + if (wxGetApp().m_enco_waitingUntilAllDone) { + wxGetApp().m_enco_waitingUntilAllDone = false; + wxGetApp().m_enco_semAllDone.Post(); + } + } +} + +void *OPJEncoThread::Entry() +{ + wxString text; + + 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("Enco thread %d started"), m_canvas->m_childframe->m_winnumber); + WriteText(text); + + // set handler properties + wxJPEG2000Handler *jpeg2000handler = (wxJPEG2000Handler *) wxImage::FindHandler(wxBITMAP_TYPE_JPEG2000); + jpeg2000handler->m_subsampling = wxGetApp().m_subsampling; + jpeg2000handler->m_origin = wxGetApp().m_origin; + jpeg2000handler->m_rates = wxGetApp().m_rates; + jpeg2000handler->m_quality = wxGetApp().m_quality; + jpeg2000handler->m_enablequality = wxGetApp().m_enablequality; + jpeg2000handler->m_multicomp = wxGetApp().m_multicomp; + jpeg2000handler->m_irreversible = wxGetApp().m_irreversible; + jpeg2000handler->m_resolutions = wxGetApp().m_resolutions; + jpeg2000handler->m_progression = wxGetApp().m_progression; + jpeg2000handler->m_cbsize = wxGetApp().m_cbsize; + jpeg2000handler->m_prsize = wxGetApp().m_prsize; + jpeg2000handler->m_tsize = wxGetApp().m_tsize; + jpeg2000handler->m_torigin = wxGetApp().m_torigin; + jpeg2000handler->m_enablesop = wxGetApp().m_enablesop; + jpeg2000handler->m_enableeph = wxGetApp().m_enableeph; + jpeg2000handler->m_enablebypass = wxGetApp().m_enablebypass; + jpeg2000handler->m_enablerestart = wxGetApp().m_enablerestart; + jpeg2000handler->m_enablereset = wxGetApp().m_enablereset; + jpeg2000handler->m_enablesegmark = wxGetApp().m_enablesegmark; + jpeg2000handler->m_enableerterm = wxGetApp().m_enableerterm; + jpeg2000handler->m_enablevsc = wxGetApp().m_enablevsc; + jpeg2000handler->m_enableidx = wxGetApp().m_enableidx; + jpeg2000handler->m_index = m_canvas->m_savename.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR) + wxGetApp().m_index; + jpeg2000handler->m_enablecomm = wxGetApp().m_enablecomm; + jpeg2000handler->m_comment = wxGetApp().m_comment; + jpeg2000handler->m_enablepoc = wxGetApp().m_enablepoc; + jpeg2000handler->m_poc = wxGetApp().m_poc; + + // save the file + if (!m_canvas->m_image100.SaveFile(m_canvas->m_savename.GetFullPath(), (wxBitmapType) wxBITMAP_TYPE_JPEG2000)) { + WriteText(wxT("Can't save image")); + return NULL; + } + + text.Printf(wxT("Enco thread %d finished"), m_canvas->m_childframe->m_winnumber); + WriteText(text); + return NULL; +} + + +///////////////////////////////////////////////////////////////////// +// Decoding thread class +///////////////////////////////////////////////////////////////////// +OPJDecoThread::OPJDecoThread(OPJCanvas *canvas) + : wxThread() +{ + m_count = 0; + m_canvas = canvas; +} + +void OPJDecoThread::WriteText(const wxString& text) +{ + wxString msg; + + // we use a fake event and post it for inter-thread gui communication + wxCommandEvent event(wxEVT_COMMAND_MENU_SELECTED, OPJFRAME_THREADLOGMSG); + event.SetInt(-1); + msg << text; + event.SetString(msg); + wxPostEvent(this->m_canvas->m_childframe->m_frame, event); + +/* + // before doing any GUI calls we must ensure that this thread is the only + // one doing it! + +#ifndef __WXGTK__ + wxMutexGuiEnter(); +#endif // __WXGTK__ + + msg << text; + m_canvas->WriteText(msg); + +#ifndef __WXGTK__ + wxMutexGuiLeave(); +#endif // __WXGTK__ +*/ +} + +void OPJDecoThread::OnExit() +{ + wxCriticalSectionLocker locker(wxGetApp().m_deco_critsect); + + wxArrayThread& dthreads = wxGetApp().m_deco_threads; + dthreads.Remove(this); + + if (dthreads.IsEmpty() ) + { + // signal the main thread that there are no more threads left if it is + // waiting for us + if (wxGetApp().m_deco_waitingUntilAllDone) { + wxGetApp().m_deco_waitingUntilAllDone = false; + wxGetApp().m_deco_semAllDone.Post(); + } + } +} + +void *OPJDecoThread::Entry() +{ + + wxString text; + + //srand(GetId()); + //int m_countnum = rand() % 9; + //text.Printf(wxT("Deco thread 0x%lx started (priority = %u, time = %d)."), + // GetId(), GetPriority(), m_countnum); + + // we have started + text.Printf(wxT("Deco thread %d started"), m_canvas->m_childframe->m_winnumber); + WriteText(text); + + // prepare dummy wximage + wxBitmap bitmap(100, 100); + wxImage image(100, 100, true); //= bitmap.ConvertToImage(); + image.Destroy(); + + // show image full name + WriteText(m_canvas->m_fname.GetFullPath()); + + // set handler properties + wxJPEG2000Handler *jpeg2000handler = (wxJPEG2000Handler *) wxImage::FindHandler(wxBITMAP_TYPE_JPEG2000); + jpeg2000handler->m_reducefactor = wxGetApp().m_reducefactor; + jpeg2000handler->m_qualitylayers = wxGetApp().m_qualitylayers; + jpeg2000handler->m_components = wxGetApp().m_components; + jpeg2000handler->m_framenum = wxGetApp().m_framenum; +#ifdef USE_JPWL + jpeg2000handler->m_enablejpwl = wxGetApp().m_enablejpwl; + jpeg2000handler->m_expcomps = wxGetApp().m_expcomps; + jpeg2000handler->m_maxtiles = wxGetApp().m_maxtiles; +#endif // USE_JPWL + +#ifdef USE_MXF + wxMXFHandler *mxfffhandler = (wxMXFHandler *) wxImage::FindHandler(wxBITMAP_TYPE_MXF); + mxfffhandler->m_reducefactor = wxGetApp().m_reducefactor; + mxfffhandler->m_qualitylayers = wxGetApp().m_qualitylayers; + mxfffhandler->m_components = wxGetApp().m_components; + mxfffhandler->m_framenum = wxGetApp().m_framenum; + mxfffhandler->m_filename = m_canvas->m_fname; +#ifdef USE_JPWL + mxfffhandler->m_enablejpwl = wxGetApp().m_enablejpwl; + mxfffhandler->m_expcomps = wxGetApp().m_expcomps; + mxfffhandler->m_maxtiles = wxGetApp().m_maxtiles; +#endif // USE_JPWL +#endif // USE_MXF + + // if decoding is enabled... + if (wxGetApp().m_enabledeco) { + + // load the file + if (!image.LoadFile(m_canvas->m_fname.GetFullPath(), wxBITMAP_TYPE_ANY, 0)) { + WriteText(wxT("Can't load image!")); + return NULL; + } + + } else { + + // display a warning + if (!image.Create(300, 5, false)) { + WriteText(wxT("Can't create image!")); + return NULL; + } + + } + + // assign 100% image + m_canvas->m_image100 = wxBitmap(image); + + // signal the frame to refresh the canvas + wxCommandEvent event(wxEVT_COMMAND_MENU_SELECTED, OPJFRAME_VIEWFIT); + event.SetString(wxT("Fit me")); + event.SetInt(m_canvas->m_childframe->m_winnumber); + wxPostEvent(m_canvas->m_childframe->m_frame, event); + + // 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 +#ifndef __WXGTK__ + //m_canvas->m_childframe->m_frame->Rescale(zooml, m_canvas->m_childframe); +#endif // __WXGTK__ + + //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); + return NULL; + +} + +///////////////////////////////////////////////////////////////////// +// Parsing thread class +///////////////////////////////////////////////////////////////////// + +OPJParseThread::OPJParseThread(OPJMarkerTree *tree, wxTreeItemId parentid) + : wxThread() +{ + m_count = 0; + m_tree = tree; + m_parentid = parentid; +} + +void OPJParseThread::WriteText(const wxString& text) +{ + wxString msg; + + // we use a fake event and post it for inter-thread gui communication + wxCommandEvent event(wxEVT_COMMAND_MENU_SELECTED, OPJFRAME_THREADLOGMSG); + event.SetInt(-1); + msg << text; + event.SetString(msg); + wxPostEvent(this->m_tree->m_childframe->m_frame, event); + +/* // before doing any GUI calls we must ensure that this thread is the only + // one doing it! + +#ifndef __WXGTK__ + wxMutexGuiEnter(); +#endif // __WXGTK + + msg << text; + m_tree->WriteText(msg); + +#ifndef __WXGTK__ + wxMutexGuiLeave(); +#endif // __WXGTK*/ +} + +void OPJParseThread::OnExit() +{ + wxCriticalSectionLocker locker(wxGetApp().m_parse_critsect); + + wxArrayThread& threads = wxGetApp().m_parse_threads; + threads.Remove(this); + + 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) { + wxGetApp().m_parse_waitingUntilAllDone = false; + wxGetApp().m_parse_semAllDone.Post(); + } + } +} + +void *OPJParseThread::Entry() +{ + + printf("Entering\n\n"); + + wxString text; + + srand(GetId()); + int m_countnum = rand() % 9; + text.Printf(wxT("Parse thread 0x%lx started (priority = %u, time = %d)."), + GetId(), GetPriority(), m_countnum); + WriteText(text); + LoadFile(m_tree->m_fname); + text.Printf(wxT("Parse thread 0x%lx finished."), GetId()); + WriteText(text); + + + //wxLogMessage(wxT("Entering\n")); //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] Parse thread 0x%lx here."), m_count, GetId()); + WriteText(text); + + // wxSleep() can't be called from non-GUI thread! + wxThread::Sleep(10); + }*/ + + // wxLogMessage(text); -- test wxLog thread safeness + + printf("Exiting\n\n"); + + return NULL; +} + + +/////////////////////////////////////////// +// Parsing hread and related +/////////////////////////////////////////// + +#if USE_GENERIC_TREECTRL +BEGIN_EVENT_TABLE(OPJMarkerTree, wxGenericTreeCtrl) +#else +BEGIN_EVENT_TABLE(OPJMarkerTree, wxTreeCtrl) +#endif + /*EVT_TREE_BEGIN_DRAG(TreeTest_Ctrl, OPJMarkerTree::OnBeginDrag) + EVT_TREE_BEGIN_RDRAG(TreeTest_Ctrl, OPJMarkerTree::OnBeginRDrag) + EVT_TREE_END_DRAG(TreeTest_Ctrl, OPJMarkerTree::OnEndDrag)*/ + /*EVT_TREE_BEGIN_LABEL_EDIT(TreeTest_Ctrl, OPJMarkerTree::OnBeginLabelEdit) + EVT_TREE_END_LABEL_EDIT(TreeTest_Ctrl, OPJMarkerTree::OnEndLabelEdit)*/ + /*EVT_TREE_DELETE_ITEM(TreeTest_Ctrl, OPJMarkerTree::OnDeleteItem)*/ +#if 0 // there are so many of those that logging them causes flicker + /*EVT_TREE_GET_INFO(TreeTest_Ctrl, OPJMarkerTree::OnGetInfo)*/ +#endif + /*EVT_TREE_SET_INFO(TreeTest_Ctrl, OPJMarkerTree::OnSetInfo) + EVT_TREE_ITEM_EXPANDED(TreeTest_Ctrl, OPJMarkerTree::OnItemExpanded)*/ + EVT_TREE_ITEM_EXPANDING(TreeTest_Ctrl, OPJMarkerTree::OnItemExpanding) + /*EVT_TREE_ITEM_COLLAPSED(TreeTest_Ctrl, OPJMarkerTree::OnItemCollapsed) + EVT_TREE_ITEM_COLLAPSING(TreeTest_Ctrl, OPJMarkerTree::OnItemCollapsing)*/ + + EVT_TREE_SEL_CHANGED(TreeTest_Ctrl, OPJMarkerTree::OnSelChanged) + /*EVT_TREE_SEL_CHANGING(TreeTest_Ctrl, OPJMarkerTree::OnSelChanging)*/ + /*EVT_TREE_KEY_DOWN(TreeTest_Ctrl, OPJMarkerTree::OnTreeKeyDown)*/ + /*EVT_TREE_ITEM_ACTIVATED(TreeTest_Ctrl, OPJMarkerTree::OnItemActivated)*/ + + // so many differents ways to handle right mouse button clicks... + /*EVT_CONTEXT_MENU(OPJMarkerTree::OnContextMenu)*/ + // 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_RIGHT_CLICK(TreeTest_Ctrl, OPJMarkerTree::OnItemRClick)*/ + + /*EVT_RIGHT_DOWN(OPJMarkerTree::OnRMouseDown) + EVT_RIGHT_UP(OPJMarkerTree::OnRMouseUp) + EVT_RIGHT_DCLICK(OPJMarkerTree::OnRMouseDClick)*/ +END_EVENT_TABLE() + +// OPJMarkerTree implementation +#if USE_GENERIC_TREECTRL +IMPLEMENT_DYNAMIC_CLASS(OPJMarkerTree, wxGenericTreeCtrl) +#else +IMPLEMENT_DYNAMIC_CLASS(OPJMarkerTree, wxTreeCtrl) +#endif + +OPJMarkerTree::OPJMarkerTree(wxWindow *parent, OPJChildFrame *subframe, wxFileName fname, wxString name, const wxWindowID id, + const wxPoint& pos, const wxSize& size, long style) + : wxTreeCtrl(parent, id, pos, size, style) +{ + m_reverseSort = false; + m_fname = fname; + + m_peektextCtrl = ((OPJFrame *) (parent->GetParent()->GetParent()))->m_textCtrlbrowse; + CreateImageList(); + + // Add some items to the tree + //AddTestItemsToTree(5, 5); + int image = wxGetApp().ShowImages() ? OPJMarkerTree::TreeCtrlIcon_Folder : -1; + wxTreeItemId rootId = AddRoot(name, + image, image, + new OPJMarkerData(name)); + + OPJParseThread *pthread = CreateParseThread(0x00, subframe); + if (pthread->Run() != wxTHREAD_NO_ERROR) + wxLogMessage(wxT("Can't start parse thread!")); + else + wxLogMessage(wxT("New parse thread started.")); + + m_childframe = subframe; +} + +void OPJMarkerTree::CreateImageList(int size) +{ + if (size == -1) { + SetImageList(NULL); + return; + } + if (size == 0) + size = m_imageSize; + else + m_imageSize = size; + + // Make an image list containing small icons + wxImageList *images = new wxImageList(size, size, true); + + // should correspond to TreeCtrlIcon_xxx enum + wxBusyCursor wait; + wxIcon icons[5]; + icons[0] = wxIcon(icon1_xpm); + icons[1] = wxIcon(icon2_xpm); + icons[2] = wxIcon(icon3_xpm); + icons[3] = wxIcon(icon4_xpm); + icons[4] = wxIcon(icon5_xpm); + + int sizeOrig = icons[0].GetWidth(); + for (size_t i = 0; i < WXSIZEOF(icons); i++) { + if (size == sizeOrig) { + images->Add(icons[i]); + } else { + images->Add(wxBitmap(wxBitmap(icons[i]).ConvertToImage().Rescale(size, size))); + } + } + + AssignImageList(images); +} + +#if USE_GENERIC_TREECTRL || !defined(__WXMSW__) +void OPJMarkerTree::CreateButtonsImageList(int size) +{ + if ( size == -1 ) { + SetButtonsImageList(NULL); + return; + } + + // Make an image list containing small icons + wxImageList *images = new wxImageList(size, size, true); + + // should correspond to TreeCtrlIcon_xxx enum + wxBusyCursor wait; + wxIcon icons[4]; + icons[0] = wxIcon(icon3_xpm); // closed + icons[1] = wxIcon(icon3_xpm); // closed, selected + icons[2] = wxIcon(icon5_xpm); // open + icons[3] = wxIcon(icon5_xpm); // open, selected + + for ( size_t i = 0; i < WXSIZEOF(icons); i++ ) { + int sizeOrig = icons[i].GetWidth(); + if ( size == sizeOrig ) { + images->Add(icons[i]); + } else { + images->Add(wxBitmap(wxBitmap(icons[i]).ConvertToImage().Rescale(size, size))); + } + } + + AssignButtonsImageList(images); +#else +void OPJMarkerTree::CreateButtonsImageList(int WXUNUSED(size)) +{ +#endif +} + +void OPJParseThread::LoadFile(wxFileName fname) +{ + wxTreeItemId rootid; + + // this is the root node + int image = wxGetApp().ShowImages() ? m_tree->TreeCtrlIcon_Folder : -1; + + if (this->m_parentid) { + // leaf of a tree + rootid = m_parentid; + m_tree->SetItemText(rootid, wxT("Parsing...")); + + } else { + + // delete the existing tree hierarchy + m_tree->DeleteAllItems(); + + // new tree + rootid = m_tree->AddRoot(wxT("Parsing..."), + image, + image, + new OPJMarkerData(fname.GetFullPath()) + ); + //m_tree->SetItemFont(rootid, *wxITALIC_FONT); + m_tree->SetItemBold(rootid); + } + + // open the file + wxFile m_file(fname.GetFullPath().c_str(), wxFile::read); + + // parsing enabled? + if (wxGetApp().m_enableparse) { + + // what is the extension? + if ((fname.GetExt() == wxT("j2k")) || (fname.GetExt() == wxT("j2c"))) { + + // parse the file + ParseJ2KFile(&m_file, 0, m_file.Length(), rootid); + + } else if ((fname.GetExt() == wxT("jp2")) || (fname.GetExt() == wxT("mj2"))) { + + // parse the file + if (this->m_parentid) { + //WriteText(wxT("Only a subsection of jp2")); + OPJMarkerData *data = (OPJMarkerData *) m_tree->GetItemData(rootid); + ParseJ2KFile(&m_file, data->m_start, data->m_length, rootid); + m_tree->Expand(rootid); + + } else { + // as usual + ParseJP2File(&m_file, 0, m_file.Length(), rootid); + } + + } else { + + // unknown extension + WriteText(wxT("Unknown file format!")); + + } + + } + + // this is the root node + if (this->m_parentid) + m_tree->SetItemText(rootid, wxT("Codestream")); + else + //m_tree->SetItemText(rootid, wxString::Format(wxT("%s (%d B)"), fname.GetFullName(), m_file.Length())); + m_tree->SetItemText(rootid, fname.GetFullName()); + + // close the file + m_file.Close(); + + WriteText(wxT("Parsing finished!")); +} + +/*int OPJMarkerTree::OnCompareItems(const wxTreeItemId& item1, + const wxTreeItemId& item2) +{ + if ( m_reverseSort ) + { + // just exchange 1st and 2nd items + return wxTreeCtrl::OnCompareItems(item2, item1); + } + else + { + return wxTreeCtrl::OnCompareItems(item1, item2); + } +}*/ + +/*void OPJMarkerTree::AddItemsRecursively(const wxTreeItemId& idParent, + size_t numChildren, + size_t depth, + size_t folder) +{ + if ( depth > 0 ) + { + bool hasChildren = depth > 1; + + wxString str; + for ( size_t n = 0; n < numChildren; n++ ) + { + // at depth 1 elements won't have any more children + if ( hasChildren ) + str.Printf(wxT("%s child %u"), wxT("Folder"), unsigned(n + 1)); + else + str.Printf(wxT("%s child %u.%u"), wxT("File"), unsigned(folder), unsigned(n + 1)); + + // here we pass to AppendItem() normal and selected item images (we + // suppose that selected image follows the normal one in the enum) + int image, imageSel; + if ( wxGetApp().ShowImages() ) + { + image = depth == 1 ? TreeCtrlIcon_File : TreeCtrlIcon_Folder; + imageSel = image + 1; + } + else + { + image = imageSel = -1; + } + wxTreeItemId id = AppendItem(idParent, str, image, imageSel, + new OPJMarkerData(str)); + + // and now we also set the expanded one (only for the folders) + if ( hasChildren && wxGetApp().ShowImages() ) + { + SetItemImage(id, TreeCtrlIcon_FolderOpened, + wxTreeItemIcon_Expanded); + } + + // remember the last child for OnEnsureVisible() + if ( !hasChildren && n == numChildren - 1 ) + { + m_lastItem = id; + } + + AddItemsRecursively(id, numChildren, depth - 1, n + 1); + } + } + //else: done! +}*/ + +/*void OPJMarkerTree::AddTestItemsToTree(size_t numChildren, + size_t depth) +{ + int image = wxGetApp().ShowImages() ? OPJMarkerTree::TreeCtrlIcon_Folder : -1; + wxTreeItemId rootId = AddRoot(wxT("Root"), + image, image, + new OPJMarkerData(wxT("Root item"))); + if ( image != -1 ) + { + SetItemImage(rootId, TreeCtrlIcon_FolderOpened, wxTreeItemIcon_Expanded); + } + + AddItemsRecursively(rootId, numChildren, depth, 0); + + // set some colours/fonts for testing + SetItemFont(rootId, *wxITALIC_FONT); + + wxTreeItemIdValue cookie; + wxTreeItemId id = GetFirstChild(rootId, cookie); + SetItemTextColour(id, *wxBLUE); + + id = GetNextChild(rootId, cookie); + id = GetNextChild(rootId, cookie); + SetItemTextColour(id, *wxRED); + SetItemBackgroundColour(id, *wxLIGHT_GREY); +}*/ + +/*void OPJMarkerTree::GetItemsRecursively(const wxTreeItemId& idParent, + wxTreeItemIdValue cookie) +{ + wxTreeItemId id; + + if ( !cookie ) + id = GetFirstChild(idParent, cookie); + else + id = GetNextChild(idParent, cookie); + + if ( !id.IsOk() ) + return; + + wxString text = GetItemText(id); + wxLogMessage(text); + + if (ItemHasChildren(id)) + GetItemsRecursively(id); + + GetItemsRecursively(idParent, cookie); +}*/ + +/*void OPJMarkerTree::DoToggleIcon(const wxTreeItemId& item) +{ + int image = (GetItemImage(item) == TreeCtrlIcon_Folder) + ? TreeCtrlIcon_File + : TreeCtrlIcon_Folder; + SetItemImage(item, image, wxTreeItemIcon_Normal); + + image = (GetItemImage(item) == TreeCtrlIcon_FolderSelected) + ? TreeCtrlIcon_FileSelected + : TreeCtrlIcon_FolderSelected; + SetItemImage(item, image, wxTreeItemIcon_Selected); +}*/ + +void OPJMarkerTree::LogEvent(const wxChar *name, const wxTreeEvent& event) +{ + wxTreeItemId item = event.GetItem(); + wxString text; + if ( item.IsOk() ) + text << wxT('"') << GetItemText(item).c_str() << wxT('"'); + else + text = wxT("invalid item"); + wxLogMessage(wxT("%s(%s)"), name, text.c_str()); +} + +OPJParseThread *OPJMarkerTree::CreateParseThread(wxTreeItemId parentid, OPJChildFrame *subframe) +{ + OPJParseThread *pthread = new OPJParseThread(this, parentid); + + if (pthread->Create() != wxTHREAD_NO_ERROR) + wxLogError(wxT("Can't create parse thread!")); + + wxCriticalSectionLocker enter(wxGetApp().m_parse_critsect); + wxGetApp().m_parse_threads.Add(pthread); + + return pthread; +} + + +/*// avoid repetition +#define TREE_EVENT_HANDLER(name) \ +void OPJMarkerTree::name(wxTreeEvent& event) \ +{ \ + LogEvent(_T(#name), event); \ + SetLastItem(wxTreeItemId()); \ + event.Skip(); \ +}*/ + +/*TREE_EVENT_HANDLER(OnBeginRDrag)*/ +/*TREE_EVENT_HANDLER(OnDeleteItem)*/ +/*TREE_EVENT_HANDLER(OnGetInfo) +TREE_EVENT_HANDLER(OnSetInfo)*/ +/*TREE_EVENT_HANDLER(OnItemExpanded) +TREE_EVENT_HANDLER(OnItemExpanding)*/ +/*TREE_EVENT_HANDLER(OnItemCollapsed)*/ +/*TREE_EVENT_HANDLER(OnSelChanged) +TREE_EVENT_HANDLER(OnSelChanging)*/ + +/*#undef TREE_EVENT_HANDLER*/ + +void OPJMarkerTree::OnItemExpanding(wxTreeEvent& event) +{ + wxTreeItemId item = event.GetItem(); + OPJMarkerData* data = (OPJMarkerData *) GetItemData(item); + wxString text; + + if (item.IsOk()) + text << wxT('"') << GetItemText(item).c_str() << wxT('"'); + else + text = wxT("invalid item"); + + if (wxStrcmp(data->GetDesc1(), wxT("INFO-CSTREAM"))) + return; + + wxLogMessage(wxT("Expanding... (%s -> %s, %s, %d, %d)"), + text.c_str(), data->GetDesc1(), data->GetDesc2(), + data->m_start, data->m_length); + + // the codestream box is being asked for expansion + wxTreeItemIdValue cookie; + if (!GetFirstChild(item, cookie).IsOk()) { + OPJParseThread *pthread = CreateParseThread(item); + if (pthread->Run() != wxTHREAD_NO_ERROR) + wxLogMessage(wxT("Can't start parse thread!")); + else + wxLogMessage(wxT("New parse thread started.")); + } +} + +void OPJMarkerTree::OnSelChanged(wxTreeEvent& event) +{ + int bunch_linesize = 16; + int bunch_numlines = 7; + + wxTreeItemId item = event.GetItem(); + OPJMarkerData* data = (OPJMarkerData *) GetItemData(item); + wxString text; + int l, c, pos = 0, pre_pos; + + m_peektextCtrl->Clear(); + + /*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");*/ + + // open the file and browse a little + wxFile *fp = new wxFile(m_fname.GetFullPath().c_str(), wxFile::read); + + // go to position claimed + fp->Seek(data->m_start, wxFromStart); + + // read a bunch + int max_read = wxMin(wxFileOffset(bunch_linesize * bunch_numlines), data->m_length - data->m_start + 1); + if (data->m_desc == wxT("MARK (65380)")) { + /*wxLogMessage(data->m_desc);*/ + max_read = data->m_length - data->m_start + 1; + bunch_numlines = (int) ceil((float) max_read / (float) bunch_linesize); + } + unsigned char *buffer = new unsigned char[bunch_linesize * bunch_numlines]; + 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("%010d:"), data->m_start + pos); + + pre_pos = pos; + + // add hex browsing text + for (c = 0; c < bunch_linesize; c++) { + + if (!(c % 8)) + text << wxT(" "); + + if (pos < max_read) { + text << wxString::Format(wxT("%02X "), buffer[pos]); + } else + text << wxT(" "); + pos++; + } + + text << wxT(" "); + + // add char browsing text + for (c = 0; c < bunch_linesize; c++) { + + if (pre_pos < max_read) { + 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::FromAscii((char) buffer[pre_pos]) << wxT("."); + } else + text << wxT(" "); + pre_pos++; + } + + text << wxT("\n"); + + } + + // close the file + fp->Close(); + + m_peektextCtrl->WriteText(text); + + delete buffer; +} + +/*void LogKeyEvent(const wxChar *name, const wxKeyEvent& event) +{ + wxString key; + long keycode = event.GetKeyCode(); + { + switch ( keycode ) + { + case WXK_BACK: key = wxT("BACK"); break; + case WXK_TAB: key = wxT("TAB"); break; + case WXK_RETURN: key = wxT("RETURN"); break; + case WXK_ESCAPE: key = wxT("ESCAPE"); break; + case WXK_SPACE: key = wxT("SPACE"); break; + case WXK_DELETE: key = wxT("DELETE"); break; + case WXK_START: key = wxT("START"); break; + case WXK_LBUTTON: key = wxT("LBUTTON"); break; + case WXK_RBUTTON: key = wxT("RBUTTON"); break; + case WXK_CANCEL: key = wxT("CANCEL"); break; + case WXK_MBUTTON: key = wxT("MBUTTON"); break; + case WXK_CLEAR: key = wxT("CLEAR"); break; + case WXK_SHIFT: key = wxT("SHIFT"); break; + case WXK_ALT: key = wxT("ALT"); break; + case WXK_CONTROL: key = wxT("CONTROL"); break; + case WXK_MENU: key = wxT("MENU"); break; + case WXK_PAUSE: key = wxT("PAUSE"); break; + case WXK_CAPITAL: key = wxT("CAPITAL"); break; + case WXK_END: key = wxT("END"); break; + case WXK_HOME: key = wxT("HOME"); break; + case WXK_LEFT: key = wxT("LEFT"); break; + case WXK_UP: key = wxT("UP"); break; + case WXK_RIGHT: key = wxT("RIGHT"); break; + case WXK_DOWN: key = wxT("DOWN"); break; + case WXK_SELECT: key = wxT("SELECT"); break; + case WXK_PRINT: key = wxT("PRINT"); break; + case WXK_EXECUTE: key = wxT("EXECUTE"); break; + case WXK_SNAPSHOT: key = wxT("SNAPSHOT"); break; + case WXK_INSERT: key = wxT("INSERT"); break; + case WXK_HELP: key = wxT("HELP"); break; + case WXK_NUMPAD0: key = wxT("NUMPAD0"); break; + case WXK_NUMPAD1: key = wxT("NUMPAD1"); break; + case WXK_NUMPAD2: key = wxT("NUMPAD2"); break; + case WXK_NUMPAD3: key = wxT("NUMPAD3"); break; + case WXK_NUMPAD4: key = wxT("NUMPAD4"); break; + case WXK_NUMPAD5: key = wxT("NUMPAD5"); break; + case WXK_NUMPAD6: key = wxT("NUMPAD6"); break; + case WXK_NUMPAD7: key = wxT("NUMPAD7"); break; + case WXK_NUMPAD8: key = wxT("NUMPAD8"); break; + case WXK_NUMPAD9: key = wxT("NUMPAD9"); break; + case WXK_MULTIPLY: key = wxT("MULTIPLY"); break; + case WXK_ADD: key = wxT("ADD"); break; + case WXK_SEPARATOR: key = wxT("SEPARATOR"); break; + case WXK_SUBTRACT: key = wxT("SUBTRACT"); break; + case WXK_DECIMAL: key = wxT("DECIMAL"); break; + case WXK_DIVIDE: key = wxT("DIVIDE"); break; + case WXK_F1: key = wxT("F1"); break; + case WXK_F2: key = wxT("F2"); break; + case WXK_F3: key = wxT("F3"); break; + case WXK_F4: key = wxT("F4"); break; + case WXK_F5: key = wxT("F5"); break; + case WXK_F6: key = wxT("F6"); break; + case WXK_F7: key = wxT("F7"); break; + case WXK_F8: key = wxT("F8"); break; + case WXK_F9: key = wxT("F9"); break; + case WXK_F10: key = wxT("F10"); break; + case WXK_F11: key = wxT("F11"); break; + case WXK_F12: key = wxT("F12"); break; + case WXK_F13: key = wxT("F13"); break; + case WXK_F14: key = wxT("F14"); break; + case WXK_F15: key = wxT("F15"); break; + case WXK_F16: key = wxT("F16"); break; + case WXK_F17: key = wxT("F17"); break; + case WXK_F18: key = wxT("F18"); break; + case WXK_F19: key = wxT("F19"); break; + case WXK_F20: key = wxT("F20"); break; + case WXK_F21: key = wxT("F21"); break; + case WXK_F22: key = wxT("F22"); break; + case WXK_F23: key = wxT("F23"); break; + case WXK_F24: key = wxT("F24"); break; + case WXK_NUMLOCK: key = wxT("NUMLOCK"); break; + case WXK_SCROLL: key = wxT("SCROLL"); break; + case WXK_PAGEUP: key = wxT("PAGEUP"); break; + case WXK_PAGEDOWN: key = wxT("PAGEDOWN"); break; + case WXK_NUMPAD_SPACE: key = wxT("NUMPAD_SPACE"); break; + case WXK_NUMPAD_TAB: key = wxT("NUMPAD_TAB"); break; + case WXK_NUMPAD_ENTER: key = wxT("NUMPAD_ENTER"); break; + case WXK_NUMPAD_F1: key = wxT("NUMPAD_F1"); break; + case WXK_NUMPAD_F2: key = wxT("NUMPAD_F2"); break; + case WXK_NUMPAD_F3: key = wxT("NUMPAD_F3"); break; + case WXK_NUMPAD_F4: key = wxT("NUMPAD_F4"); break; + case WXK_NUMPAD_HOME: key = wxT("NUMPAD_HOME"); break; + case WXK_NUMPAD_LEFT: key = wxT("NUMPAD_LEFT"); break; + case WXK_NUMPAD_UP: key = wxT("NUMPAD_UP"); break; + case WXK_NUMPAD_RIGHT: key = wxT("NUMPAD_RIGHT"); break; + case WXK_NUMPAD_DOWN: key = wxT("NUMPAD_DOWN"); break; + case WXK_NUMPAD_PAGEUP: key = wxT("NUMPAD_PAGEUP"); break; + case WXK_NUMPAD_PAGEDOWN: key = wxT("NUMPAD_PAGEDOWN"); break; + case WXK_NUMPAD_END: key = wxT("NUMPAD_END"); break; + case WXK_NUMPAD_BEGIN: key = wxT("NUMPAD_BEGIN"); break; + case WXK_NUMPAD_INSERT: key = wxT("NUMPAD_INSERT"); break; + case WXK_NUMPAD_DELETE: key = wxT("NUMPAD_DELETE"); break; + case WXK_NUMPAD_EQUAL: key = wxT("NUMPAD_EQUAL"); break; + case WXK_NUMPAD_MULTIPLY: key = wxT("NUMPAD_MULTIPLY"); break; + case WXK_NUMPAD_ADD: key = wxT("NUMPAD_ADD"); break; + case WXK_NUMPAD_SEPARATOR: key = wxT("NUMPAD_SEPARATOR"); break; + case WXK_NUMPAD_SUBTRACT: key = wxT("NUMPAD_SUBTRACT"); break; + case WXK_NUMPAD_DECIMAL: key = wxT("NUMPAD_DECIMAL"); break; + + default: + { + if ( keycode < 128 && wxIsprint((int)keycode) ) + key.Printf(wxT("'%c'"), (char)keycode); + else if ( keycode > 0 && keycode < 27 ) + key.Printf(_("Ctrl-%c"), wxT('A') + keycode - 1); + else + key.Printf(wxT("unknown (%ld)"), keycode); + } + } + } + + wxLogMessage(wxT("%s event: %s (flags = %c%c%c%c)"), + name, + key.c_str(), + event.ControlDown() ? wxT('C') : wxT('-'), + event.AltDown() ? wxT('A') : wxT('-'), + event.ShiftDown() ? wxT('S') : wxT('-'), + event.MetaDown() ? wxT('M') : wxT('-')); +} + +void OPJMarkerTree::OnTreeKeyDown(wxTreeEvent& event) +{ + LogKeyEvent(wxT("Tree key down "), event.GetKeyEvent()); + + event.Skip(); +}*/ + +/*void OPJMarkerTree::OnBeginDrag(wxTreeEvent& event) +{ + // need to explicitly allow drag + if ( event.GetItem() != GetRootItem() ) + { + m_draggedItem = event.GetItem(); + + wxLogMessage(wxT("OnBeginDrag: started dragging %s"), + GetItemText(m_draggedItem).c_str()); + + event.Allow(); + } + else + { + wxLogMessage(wxT("OnBeginDrag: this item can't be dragged.")); + } +} + +void OPJMarkerTree::OnEndDrag(wxTreeEvent& event) +{ + wxTreeItemId itemSrc = m_draggedItem, + itemDst = event.GetItem(); + m_draggedItem = (wxTreeItemId)0l; + + // where to copy the item? + if ( itemDst.IsOk() && !ItemHasChildren(itemDst) ) + { + // copy to the parent then + itemDst = GetItemParent(itemDst); + } + + if ( !itemDst.IsOk() ) + { + wxLogMessage(wxT("OnEndDrag: can't drop here.")); + + return; + } + + wxString text = GetItemText(itemSrc); + wxLogMessage(wxT("OnEndDrag: '%s' copied to '%s'."), + text.c_str(), GetItemText(itemDst).c_str()); + + // just do append here - we could also insert it just before/after the item + // on which it was dropped, but this requires slightly more work... we also + // completely ignore the client data and icon of the old item but could + // copy them as well. + // + // Finally, we only copy one item here but we might copy the entire tree if + // we were dragging a folder. + int image = wxGetApp().ShowImages() ? TreeCtrlIcon_File : -1; + AppendItem(itemDst, text, image); +}*/ + +/*void OPJMarkerTree::OnBeginLabelEdit(wxTreeEvent& event) +{ + wxLogMessage(wxT("OnBeginLabelEdit")); + + // for testing, prevent this item's label editing + wxTreeItemId itemId = event.GetItem(); + if ( IsTestItem(itemId) ) + { + wxMessageBox(wxT("You can't edit this item.")); + + event.Veto(); + } + else if ( itemId == GetRootItem() ) + { + // test that it is possible to change the text of the item being edited + SetItemText(itemId, _T("Editing root item")); + } +} + +void OPJMarkerTree::OnEndLabelEdit(wxTreeEvent& event) +{ + wxLogMessage(wxT("OnEndLabelEdit")); + + // don't allow anything except letters in the labels + if ( !event.GetLabel().IsWord() ) + { + wxMessageBox(wxT("The new label should be a single word.")); + + event.Veto(); + } +}*/ + +/*void OPJMarkerTree::OnItemCollapsing(wxTreeEvent& event) +{ + wxLogMessage(wxT("OnItemCollapsing")); + + // for testing, prevent the user from collapsing the first child folder + wxTreeItemId itemId = event.GetItem(); + if ( IsTestItem(itemId) ) + { + wxMessageBox(wxT("You can't collapse this item.")); + + event.Veto(); + } +}*/ + +/*void OPJMarkerTree::OnItemActivated(wxTreeEvent& event) +{ + // show some info about this item + wxTreeItemId itemId = event.GetItem(); + OPJMarkerData *item = (OPJMarkerData *)GetItemData(itemId); + + if ( item != NULL ) + { + item->ShowInfo(this); + } + + wxLogMessage(wxT("OnItemActivated")); +}*/ + +void OPJMarkerTree::OnItemMenu(wxTreeEvent& event) +{ + /*wxTreeItemId itemId = event.GetItem(); + OPJMarkerData *item = itemId.IsOk() ? (OPJMarkerData *)GetItemData(itemId) + : NULL; + + wxLogMessage(wxT("OnItemMenu for item \"%s\""), item ? item->GetDesc() + : _T(""));*/ + + //wxLogMessage(wxT("EEEEEEEEEE")); + + //event.Skip(); +} + +/*void OPJMarkerTree::OnContextMenu(wxContextMenuEvent& event) +{ + wxPoint pt = event.GetPosition(); + wxTreeItemId item; + wxLogMessage(wxT("OnContextMenu at screen coords (%i, %i)"), pt.x, pt.y); + + // check if event was generated by keyboard (MSW-specific?) + if ( pt.x == -1 && pt.y == -1 ) //(this is how MSW indicates it) + { + if ( !HasFlag(wxTR_MULTIPLE) ) + item = GetSelection(); + + // attempt to guess where to show the menu + if ( item.IsOk() ) + { + // if an item was clicked, show menu to the right of it + wxRect rect; + GetBoundingRect(item, rect, true );// only the label + pt = wxPoint(rect.GetRight(), rect.GetTop()); + } + else + { + pt = wxPoint(0, 0); + } + } + else // event was generated by mouse, use supplied coords + { + pt = ScreenToClient(pt); + item = HitTest(pt); + } + + ShowMenu(item, pt); +}*/ + +/*void OPJMarkerTree::ShowMenu(wxTreeItemId id, const wxPoint& pt) +{ + wxString title; + if ( id.IsOk() ) + { + title << wxT("Menu for ") << GetItemText(id); + } + else + { + title = wxT("Menu for no particular item"); + } + +#if wxUSE_MENUS + wxMenu menu(title); + menu.Append(TreeTest_About, wxT("&About...")); + menu.AppendSeparator(); + menu.Append(TreeTest_Highlight, wxT("&Highlight item")); + menu.Append(TreeTest_Dump, wxT("&Dump")); + + PopupMenu(&menu, pt); +#endif // wxUSE_MENUS +}*/ + +/*void OPJMarkerTree::OnItemRClick(wxTreeEvent& event) +{ + wxTreeItemId itemId = event.GetItem(); + OPJMarkerData *item = itemId.IsOk() ? (OPJMarkerData *)GetItemData(itemId) + : NULL; + + wxLogMessage(wxT("Item \"%s\" right clicked"), item ? item->GetDesc() + : _T("")); + + event.Skip(); +}*/ + +/* +void OPJMarkerTree::OnRMouseDown(wxMouseEvent& event) +{ + wxLogMessage(wxT("Right mouse button down")); + + event.Skip(); +} + +void OPJMarkerTree::OnRMouseUp(wxMouseEvent& event) +{ + wxLogMessage(wxT("Right mouse button up")); + + event.Skip(); +} + +void OPJMarkerTree::OnRMouseDClick(wxMouseEvent& event) +{ + wxTreeItemId id = HitTest(event.GetPosition()); + if ( !id ) + wxLogMessage(wxT("No item under mouse")); + else + { + OPJMarkerData *item = (OPJMarkerData *)GetItemData(id); + if ( item ) + wxLogMessage(wxT("Item '%s' under mouse"), item->GetDesc()); + } + + event.Skip(); +} +*/ + +static inline const wxChar *Bool2String(bool b) +{ + return b ? wxT("") : wxT("not "); +} + +void OPJMarkerData::ShowInfo(wxTreeCtrl *tree) +{ + wxLogMessage(wxT("Item '%s': %sselected, %sexpanded, %sbold,\n") + wxT("%u children (%u immediately under this item)."), + m_desc.c_str(), + Bool2String(tree->IsSelected(GetId())), + Bool2String(tree->IsExpanded(GetId())), + Bool2String(tree->IsBold(GetId())), + unsigned(tree->GetChildrenCount(GetId())), + unsigned(tree->GetChildrenCount(GetId(), false))); +} + + diff --git a/applications/OPJViewer/source/OPJViewer.cpp b/applications/OPJViewer/source/OPJViewer.cpp index 1bc170b4..8476d919 100644 --- a/applications/OPJViewer/source/OPJViewer.cpp +++ b/applications/OPJViewer/source/OPJViewer.cpp @@ -1,1666 +1,1666 @@ -/* - * Copyright (c) 2007, Digital Signal Processing Laboratory, Universita' degli studi di Perugia (UPG), Italy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are 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. - */ -///////////////////////////////////////////////////////////////////////////// -// Name: sashtest.cpp -// Purpose: Layout/sash sample -// Author: Julian Smart -// Modified by: -// Created: 04/01/98 -// RCS-ID: $Id: sashtest.cpp,v 1.18 2005/08/23 15:54:35 ABX Exp $ -// Copyright: (c) Julian Smart -// Licence: wxWindows license -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// -// Name: treetest.cpp -// Purpose: wxTreeCtrl sample -// Author: Julian Smart -// Modified by: -// Created: 04/01/98 -// RCS-ID: $Id: treetest.cpp,v 1.110 2006/11/04 11:26:51 VZ Exp $ -// Copyright: (c) Julian Smart -// Licence: wxWindows license -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// -// 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: thread.cpp -// Purpose: wxWidgets thread sample -// Author: Guilhem Lavaux, Vadim Zeitlin -// Modified by: -// Created: 06/16/98 -// RCS-ID: $Id: thread.cpp,v 1.26 2006/10/02 05:36:28 PC Exp $ -// Copyright: (c) 1998-2002 wxWidgets team -// Licence: wxWindows license -///////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// -// Name: samples/image/image.cpp -// Purpose: sample showing operations with wxImage -// Author: Robert Roebling -// Modified by: -// Created: 1998 -// RCS-ID: $Id: image.cpp,v 1.120 2006/12/06 17:13:11 VZ Exp $ -// Copyright: (c) 1998-2005 Robert Roebling -// License: wxWindows licence -/////////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// -// Name: samples/console/console.cpp -// Purpose: A sample console (as opposed to GUI) program using wxWidgets -// Author: Vadim Zeitlin -// Modified by: -// Created: 04.10.99 -// RCS-ID: $Id: console.cpp,v 1.206 2006/11/12 19:55:19 VZ Exp $ -// Copyright: (c) 1999 Vadim Zeitlin -// Licence: wxWindows license -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// -// Name: samples/notebook/notebook.cpp -// Purpose: a sample demonstrating notebook usage -// Author: Julian Smart -// Modified by: Dimitri Schoolwerth -// Created: 26/10/98 -// RCS-ID: $Id: notebook.cpp,v 1.49 2006/11/04 18:24:07 RR Exp $ -// Copyright: (c) 1998-2002 wxWidgets team -// License: wxWindows license -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// -// 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 -///////////////////////////////////////////////////////////////////////////// - - -#include "OPJViewer.h" - -IMPLEMENT_APP(OPJViewerApp) - -// For drawing lines in a canvas -long xpos = -1; -long ypos = -1; - -int winNumber = 1; - -// Initialise this in OnInit, not statically -bool OPJViewerApp::OnInit(void) -{ - int n; -#if wxUSE_UNICODE - - wxChar **wxArgv = new wxChar *[argc + 1]; - - for (n = 0; n < argc; n++ ) { - wxMB2WXbuf warg = wxConvertMB2WX((char *) 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_PARAM, NULL, NULL, _T("input file"), - wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL | wxCMD_LINE_PARAM_MULTIPLE }, - - { wxCMD_LINE_NONE } - }; - - wxCmdLineParser parser(cmdLineDesc, argc, wxArgv); - - switch (parser.Parse()) { - case -1: - wxLogMessage(wxT("Help was given, terminating.")); - break; - - case 0: - ShowCmdLine(parser); - break; - - default: - wxLogMessage(wxT("Syntax error detected.")); - break; - } - -#endif // wxUSE_CMDLINE_PARSER - - //wxInitAllImageHandlers(); -#if wxUSE_LIBJPEG - wxImage::AddHandler( new wxJPEGHandler ); -#endif -#if wxUSE_LIBOPENJPEG - wxImage::AddHandler( new wxJPEG2000Handler ); -#endif -#if USE_MXF - wxImage::AddHandler( new wxMXFHandler ); -#endif // USE_MXF -#if OPJ_MANYFORMATS - wxImage::AddHandler( new wxBMPHandler ); - wxImage::AddHandler( new wxPNGHandler ); - wxImage::AddHandler( new wxGIFHandler ); - wxImage::AddHandler( new wxPNMHandler ); - wxImage::AddHandler( new wxTIFFHandler ); -#endif - // we use a XPM image in our HTML page - wxImage::AddHandler(new wxXPMHandler); - - // memory file system - wxFileSystem::AddHandler(new wxMemoryFSHandler); - -#ifdef OPJ_INICONFIG - //load decoding engine parameters - OPJconfig = new wxConfig(OPJ_APPLICATION, OPJ_APPLICATION_VENDOR); - - OPJconfig->Read(wxT("decode/enabledeco"), &m_enabledeco, (bool) true); - OPJconfig->Read(wxT("decode/enableparse"), &m_enableparse, (bool) true); - OPJconfig->Read(wxT("decode/resizemethod"), &m_resizemethod, (long) 0); - OPJconfig->Read(wxT("decode/xxxreducefactor"), &m_reducefactor, (long) 0); - OPJconfig->Read(wxT("decode/xxxqualitylayers"), &m_qualitylayers, (long) 0); - OPJconfig->Read(wxT("decode/xxxcomponents"), &m_components, (long) 0); - OPJconfig->Read(wxT("decode/xxxframenum"), &m_framenum, (long) 0); -#ifdef USE_JPWL - OPJconfig->Read(wxT("decode/enablejpwl"), &m_enablejpwl, (bool) true); - OPJconfig->Read(wxT("decode/expcomps"), &m_expcomps, (long) JPWL_EXPECTED_COMPONENTS); - OPJconfig->Read(wxT("decode/maxtiles"), &m_maxtiles, (long) JPWL_MAXIMUM_TILES); -#endif // USE_JPWL - - OPJconfig->Write(wxT("teststring"), wxT("This is a test value")); - OPJconfig->Write(wxT("testbool"), (bool) true); - OPJconfig->Write(wxT("testlong"), (long) 245); - - OPJconfig->Read(wxT("showtoolbar"), &m_showtoolbar, (bool) true); - OPJconfig->Read(wxT("showbrowser"), &m_showbrowser, (bool) true); - OPJconfig->Read(wxT("showpeeker"), &m_showpeeker, (bool) true); - OPJconfig->Read(wxT("browserwidth"), &m_browserwidth, (long) OPJ_BROWSER_WIDTH); - OPJconfig->Read(wxT("peekerheight"), &m_peekerheight, (long) OPJ_PEEKER_HEIGHT); - OPJconfig->Read(wxT("framewidth"), &m_framewidth, (long) OPJ_FRAME_WIDTH); - OPJconfig->Read(wxT("frameheight"), &m_frameheight, (long) OPJ_FRAME_HEIGHT); - - // load encoding engine parameters - OPJconfig->Read(wxT("encode/subsampling"), &m_subsampling, (wxString) wxT("1,1")); - OPJconfig->Read(wxT("encode/origin"), &m_origin, (wxString) wxT("0,0")); - OPJconfig->Read(wxT("encode/rates"), &m_rates, (wxString) wxT("20,10,5")); - OPJconfig->Read(wxT("encode/quality"), &m_quality, (wxString) wxT("30,35,40")); - OPJconfig->Read(wxT("encode/enablequality"), &m_enablequality, (bool) false); - OPJconfig->Read(wxT("encode/multicomp"), &m_multicomp, (bool) false); - OPJconfig->Read(wxT("encode/irreversible"), &m_irreversible, (bool) false); - OPJconfig->Read(wxT("encode/resolutions"), &m_resolutions, (int) 6); - OPJconfig->Read(wxT("encode/progression"), &m_progression, (int) 0); - OPJconfig->Read(wxT("encode/cbsize"), &m_cbsize, (wxString) wxT("32,32")); - OPJconfig->Read(wxT("encode/prsize"), &m_prsize, (wxString) wxT("[128,128],[128,128]")); - OPJconfig->Read(wxT("encode/tsize"), &m_tsize, (wxString) wxT("")); - OPJconfig->Read(wxT("encode/torigin"), &m_torigin, (wxString) wxT("0,0")); - OPJconfig->Read(wxT("encode/enablesop"), &m_enablesop, (bool) false); - OPJconfig->Read(wxT("encode/enableeph"), &m_enableeph, (bool) false); - OPJconfig->Read(wxT("encode/enablebypass"), &m_enablebypass, (bool) false); - OPJconfig->Read(wxT("encode/enablereset"), &m_enablereset, (bool) false); - OPJconfig->Read(wxT("encode/enablerestart"), &m_enablerestart, (bool) false); - OPJconfig->Read(wxT("encode/enablevsc"), &m_enablevsc, (bool) false); - OPJconfig->Read(wxT("encode/enableerterm"), &m_enableerterm, (bool) false); - OPJconfig->Read(wxT("encode/enablesegmark"), &m_enablesegmark, (bool) false); - OPJconfig->Read(wxT("encode/enablecomm"), &m_enablecomm, (bool) true); - OPJconfig->Read(wxT("encode/enablepoc"), &m_enablepoc, (bool) false); - OPJconfig->Read(wxT("encode/comment"), &m_comment, (wxString) wxT("")); - OPJconfig->Read(wxT("encode/poc"), &m_poc, (wxString) wxT("T1=0,0,1,5,3,CPRL/T1=5,0,1,6,3,CPRL")); - OPJconfig->Read(wxT("encode/enableidx"), &m_enableidx, (bool) false); - OPJconfig->Read(wxT("encode/index"), &m_index, (wxString) wxT("index.txt")); -#ifdef USE_JPWL - OPJconfig->Read(wxT("encode/enablejpwl"), &m_enablejpwle, (bool) true); - for (n = 0; n < MYJPWL_MAX_NO_TILESPECS; n++) { - OPJconfig->Read(wxT("encode/jpwl/hprotsel") + wxString::Format(wxT("%02d"), n), &m_hprotsel[n], 0); - OPJconfig->Read(wxT("encode/jpwl/htileval") + wxString::Format(wxT("%02d"), n), &m_htileval[n], 0); - OPJconfig->Read(wxT("encode/jpwl/pprotsel") + wxString::Format(wxT("%02d"), n), &m_pprotsel[n], 0); - OPJconfig->Read(wxT("encode/jpwl/ptileval") + wxString::Format(wxT("%02d"), n), &m_ptileval[n], 0); - OPJconfig->Read(wxT("encode/jpwl/ppackval") + wxString::Format(wxT("%02d"), n), &m_ppackval[n], 0); - OPJconfig->Read(wxT("encode/jpwl/sensisel") + wxString::Format(wxT("%02d"), n), &m_sensisel[n], 0); - OPJconfig->Read(wxT("encode/jpwl/stileval") + wxString::Format(wxT("%02d"), n), &m_stileval[n], 0); - } -#endif // USE_JPWL - -#else - // set decoding engine parameters - m_enabledeco = true; - m_enableparse = true; - m_resizemethod = 0; - m_reducefactor = 0; - m_qualitylayers = 0; - m_components = 0; - m_framenum = 0; -#ifdef USE_JPWL - m_enablejpwl = true; - m_expcomps = JPWL_EXPECTED_COMPONENTS; - m_maxtiles = JPWL_MAXIMUM_TILES; -#endif // USE_JPWL - m_showtoolbar = true; - m_showbrowser = true; - m_showpeeker = true; - m_browserwidth = OPJ_BROWSER_WIDTH; - m_peekerheight = OPJ_PEEKER_HEIGHT; - m_framewidth = OPJ_FRAME_WIDTH; - m_frameheight = OPJ_FRAME_HEIGHT; - - // set encoding engine parameters - m_subsampling = wxT("1,1"); - m_origin = wxT("0,0"); - m_rates = wxT("20,10,5"); - m_quality = wxT("30,35,40"); - m_enablequality = false; - m_multicomp = false; - m_irreversible = false; - m_resolutions = 6; - m_progression = 0; - m_cbsize= wxT("32,32"); - m_prsize= wxT("[128,128],[128,128]"); - m_tsize = wxT(""); - m_torigin = wxT("0,0"); - m_enablesop = false; - m_enableeph = false; - m_enablebypass = false; - m_enablereset = false; - m_enablerestart = false; - m_enablevsc = false; - m_enableerterm = false; - m_enablesegmark = false; - m_enableidx = false; - m_index = wxT("index.txt"); - m_enablecomm = true; - m_comment = wxT(""); - m_enablepoc = false; - m_poc = wxT("T1=0,0,1,5,3,CPRL/T1=5,0,1,6,3,CPRL"); -#ifdef USE_JPWL - m_enablejpwle = true; - for (n = 0; n < MYJPWL_MAX_NO_TILESPECS; n++) { - m_hprotsel[n] = 0; - m_htileval[n] = 0; - m_pprotsel[n] = 0; - m_ptileval[n] = 0; - m_sensisel[n] = 0; - m_stileval[n] = 0; - } -#endif // USE_JPWL - -#endif // OPJ_INICONFIG - - if (m_comment == wxT("")) { -#if defined __WXMSW__ - m_comment = wxT("Created by OPJViewer Win32 - OpenJPEG version "); -#elif defined __WXGTK__ - m_comment = wxT("Created by OPJViewer Lin32 - OpenJPEG version "); -#else - m_comment = wxT("Created by OPJViewer - OpenJPEG version "); -#endif - -#ifdef USE_JPWL - m_comment += wxString::Format(wxT("%s with JPWL"), (char *) opj_version()); -#else - m_comment += wxString::Format(wxT("%s"), (char *) opj_version()); -#endif - } - - // Create the main frame window - OPJFrame *frame = new OPJFrame(NULL, wxID_ANY, OPJ_APPLICATION_TITLEBAR, - wxDefaultPosition, wxSize(wxGetApp().m_framewidth, wxGetApp().m_frameheight), - 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(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 (unsigned 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; -} - -int OPJViewerApp::OnExit() -{ - int n; - -#ifdef OPJ_INICONFIG - OPJconfig->Write(wxT("decode/enabledeco"), m_enabledeco); - OPJconfig->Write(wxT("decode/enableparse"), m_enableparse); - OPJconfig->Write(wxT("decode/resizemethod"), m_resizemethod); - OPJconfig->Write(wxT("decode/reducefactor"), m_reducefactor); - OPJconfig->Write(wxT("decode/qualitylayers"), m_qualitylayers); - OPJconfig->Write(wxT("decode/components"), m_components); - OPJconfig->Write(wxT("decode/framenum"), m_framenum); -#ifdef USE_JPWL - OPJconfig->Write(wxT("decode/enablejpwl"), m_enablejpwl); - OPJconfig->Write(wxT("decode/expcomps"), m_expcomps); - OPJconfig->Write(wxT("decode/maxtiles"), m_maxtiles); -#endif // USE_JPWL - OPJconfig->Write(wxT("showtoolbar"), m_showtoolbar); - OPJconfig->Write(wxT("showbrowser"), m_showbrowser); - OPJconfig->Write(wxT("showpeeker"), m_showpeeker); - OPJconfig->Write(wxT("browserwidth"), m_browserwidth); - OPJconfig->Write(wxT("peekerheight"), m_peekerheight); - OPJconfig->Write(wxT("framewidth"), m_framewidth); - OPJconfig->Write(wxT("frameheight"), m_frameheight); - - OPJconfig->Write(wxT("encode/subsampling"), m_subsampling); - OPJconfig->Write(wxT("encode/origin"), m_origin); - OPJconfig->Write(wxT("encode/rates"), m_rates); - OPJconfig->Write(wxT("encode/quality"), m_quality); - OPJconfig->Write(wxT("encode/enablequality"), m_enablequality); - OPJconfig->Write(wxT("encode/multicomp"), m_multicomp); - OPJconfig->Write(wxT("encode/irreversible"), m_irreversible); - OPJconfig->Write(wxT("encode/resolutions"), m_resolutions); - OPJconfig->Write(wxT("encode/progression"), m_progression); - OPJconfig->Write(wxT("encode/cbsize"), m_cbsize); - OPJconfig->Write(wxT("encode/prsize"), m_prsize); - OPJconfig->Write(wxT("encode/tiles"), m_tsize); - OPJconfig->Write(wxT("encode/torigin"), m_torigin); - OPJconfig->Write(wxT("encode/enablesop"), m_enablesop); - OPJconfig->Write(wxT("encode/enableeph"), m_enableeph); - OPJconfig->Write(wxT("encode/enablebypass"), m_enablebypass); - OPJconfig->Write(wxT("encode/enablereset"), m_enablereset); - OPJconfig->Write(wxT("encode/enablerestart"), m_enablerestart); - OPJconfig->Write(wxT("encode/enablevsc"), m_enablevsc); - OPJconfig->Write(wxT("encode/enableerterm"), m_enableerterm); - OPJconfig->Write(wxT("encode/enablesegmark"), m_enablesegmark); - OPJconfig->Write(wxT("encode/enableidx"), m_enableidx); - OPJconfig->Write(wxT("encode/index"), m_index); - OPJconfig->Write(wxT("encode/enablecomm"), m_enablecomm); - OPJconfig->Write(wxT("encode/comment"), m_comment); - OPJconfig->Write(wxT("encode/enablepoc"), m_enablepoc); - OPJconfig->Write(wxT("encode/poc"), m_poc); -#ifdef USE_JPWL - OPJconfig->Write(wxT("encode/enablejpwl"), m_enablejpwle); - for (n = 0; n < MYJPWL_MAX_NO_TILESPECS; n++) { - OPJconfig->Write(wxT("encode/jpwl/hprotsel") + wxString::Format(wxT("%02d"), n), m_hprotsel[n]); - OPJconfig->Write(wxT("encode/jpwl/htileval") + wxString::Format(wxT("%02d"), n), m_htileval[n]); - OPJconfig->Write(wxT("encode/jpwl/pprotsel") + wxString::Format(wxT("%02d"), n), m_pprotsel[n]); - OPJconfig->Write(wxT("encode/jpwl/ptileval") + wxString::Format(wxT("%02d"), n), m_ptileval[n]); - OPJconfig->Write(wxT("encode/jpwl/ppackval") + wxString::Format(wxT("%02d"), n), m_ppackval[n]); - OPJconfig->Write(wxT("encode/jpwl/sensisel") + wxString::Format(wxT("%02d"), n), m_sensisel[n]); - OPJconfig->Write(wxT("encode/jpwl/stileval") + wxString::Format(wxT("%02d"), n), m_stileval[n]); - } -#endif // USE_JPWL - -#endif // OPJ_INICONFIG - - return 1; -} - -void OPJViewerApp::ShowCmdLine(const wxCmdLineParser& parser) -{ - wxString s = wxT("Command line parsed successfully:\nInput files: "); - - size_t count = parser.GetParamCount(); - for (size_t param = 0; param < count; param++) { - s << parser.GetParam(param) << ';'; - m_filelist.Add(parser.GetParam(param)); - } - - //wxLogMessage(s); -} - -// OPJFrame events - -// Event class for sending text messages between worker and GUI threads -BEGIN_EVENT_TABLE(OPJFrame, wxMDIParentFrame) - EVT_MENU(OPJFRAME_HELPABOUT, OPJFrame::OnAbout) - EVT_MENU(OPJFRAME_FILEOPEN, OPJFrame::OnFileOpen) - EVT_MENU(OPJFRAME_FILESAVEAS, OPJFrame::OnFileSaveAs) - EVT_MENU(OPJFRAME_MEMORYOPEN, OPJFrame::OnMemoryOpen) - EVT_SIZE(OPJFrame::OnSize) - 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_VIEWRELOAD, OPJFrame::OnReload) - EVT_MENU(OPJFRAME_VIEWPREVFRAME, OPJFrame::OnPrevFrame) - EVT_MENU(OPJFRAME_VIEWHOMEFRAME, OPJFrame::OnHomeFrame) - EVT_MENU(OPJFRAME_VIEWNEXTFRAME, OPJFrame::OnNextFrame) - EVT_MENU(OPJFRAME_VIEWLESSLAYERS, OPJFrame::OnLessLayers) - EVT_MENU(OPJFRAME_VIEWALLLAYERS, OPJFrame::OnAllLayers) - EVT_MENU(OPJFRAME_VIEWMORELAYERS, OPJFrame::OnMoreLayers) - EVT_MENU(OPJFRAME_VIEWLESSRES, OPJFrame::OnLessRes) - EVT_MENU(OPJFRAME_VIEWFULLRES, OPJFrame::OnFullRes) - EVT_MENU(OPJFRAME_VIEWMORERES, OPJFrame::OnMoreRes) - EVT_MENU(OPJFRAME_VIEWPREVCOMP, OPJFrame::OnPrevComp) - EVT_MENU(OPJFRAME_VIEWALLCOMPS, OPJFrame::OnAllComps) - EVT_MENU(OPJFRAME_VIEWNEXTCOMP, OPJFrame::OnNextComp) - EVT_MENU(OPJFRAME_FILETOGGLEB, OPJFrame::OnToggleBrowser) - EVT_MENU(OPJFRAME_FILETOGGLEP, OPJFrame::OnTogglePeeker) - EVT_MENU(OPJFRAME_FILETOGGLET, OPJFrame::OnToggleToolbar) - EVT_MENU(OPJFRAME_SETSENCO, OPJFrame::OnSetsEnco) - 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) - EVT_MENU(OPJFRAME_THREADLOGMSG, OPJFrame::OnThreadLogmsg) -END_EVENT_TABLE() - -// this is the frame constructor -OPJFrame::OPJFrame(wxWindow *parent, const wxWindowID id, const wxString& title, - const wxPoint& pos, const wxSize& size, const long style) - : wxMDIParentFrame(parent, id, title, pos, size, style) -{ - // file menu and its items - wxMenu *file_menu = new wxMenu; - - file_menu->Append(OPJFRAME_FILEOPEN, wxT("&Open\tCtrl+O")); - file_menu->SetHelpString(OPJFRAME_FILEOPEN, wxT("Open one or more files")); - - file_menu->Append(OPJFRAME_MEMORYOPEN, wxT("&Memory\tCtrl+M")); - file_menu->SetHelpString(OPJFRAME_MEMORYOPEN, wxT("Open a memory buffer")); - - file_menu->Append(OPJFRAME_FILECLOSE, wxT("&Close\tCtrl+C")); - file_menu->SetHelpString(OPJFRAME_FILECLOSE, wxT("Close current image")); - - file_menu->AppendSeparator(); - - file_menu->Append(OPJFRAME_FILESAVEAS, wxT("&Save as\tCtrl+S")); - file_menu->SetHelpString(OPJFRAME_FILESAVEAS, wxT("Save the current image")); - //file_menu->Enable(OPJFRAME_FILESAVEAS, false); - - file_menu->AppendSeparator(); - - file_menu->Append(OPJFRAME_FILETOGGLEB, wxT("Toggle &browser\tCtrl+B")); - file_menu->SetHelpString(OPJFRAME_FILETOGGLEB, wxT("Toggle the left browsing pane")); - - file_menu->Append(OPJFRAME_FILETOGGLEP, wxT("Toggle &peeker\tCtrl+P")); - file_menu->SetHelpString(OPJFRAME_FILETOGGLEP, wxT("Toggle the bottom peeking pane")); - - file_menu->Append(OPJFRAME_FILETOGGLET, wxT("Toggle &toolbar\tCtrl+T")); - file_menu->SetHelpString(OPJFRAME_FILETOGGLET, wxT("Toggle the toolbar")); - - file_menu->AppendSeparator(); - - 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")); - - view_menu->Append(OPJFRAME_VIEWRELOAD, wxT("&Reload image\tCtrl+R")); - view_menu->SetHelpString(OPJFRAME_VIEWRELOAD, wxT("Reload the current image")); - - view_menu->AppendSeparator(); - - view_menu->Append(OPJFRAME_VIEWPREVFRAME, wxT("&Prev frame\tLeft")); - view_menu->SetHelpString(OPJFRAME_VIEWPREVFRAME, wxT("View previous frame")); - - view_menu->Append(OPJFRAME_VIEWHOMEFRAME, wxT("&Start frame\tHome")); - view_menu->SetHelpString(OPJFRAME_VIEWHOMEFRAME, wxT("View starting frame")); - - view_menu->Append(OPJFRAME_VIEWNEXTFRAME, wxT("&Next frame\tRight")); - view_menu->SetHelpString(OPJFRAME_VIEWNEXTFRAME, wxT("View next frame")); - - view_menu->AppendSeparator(); - - view_menu->Append(OPJFRAME_VIEWLESSLAYERS, wxT("&Less layers\t-")); - view_menu->SetHelpString(OPJFRAME_VIEWLESSLAYERS, wxT("Remove a layer")); - - view_menu->Append(OPJFRAME_VIEWALLLAYERS, wxT("&All layers\t0")); - view_menu->SetHelpString(OPJFRAME_VIEWALLLAYERS, wxT("Show all layers")); - - view_menu->Append(OPJFRAME_VIEWMORELAYERS, wxT("&More layers\t+")); - view_menu->SetHelpString(OPJFRAME_VIEWMORELAYERS, wxT("Add a layer")); - - view_menu->AppendSeparator(); - - view_menu->Append(OPJFRAME_VIEWLESSRES, wxT("&Less resolution\t<")); - view_menu->SetHelpString(OPJFRAME_VIEWLESSRES, wxT("Reduce the resolution")); - - view_menu->Append(OPJFRAME_VIEWFULLRES, wxT("&Full resolution\tf")); - view_menu->SetHelpString(OPJFRAME_VIEWFULLRES, wxT("Full resolution")); - - view_menu->Append(OPJFRAME_VIEWMORERES, wxT("&More resolution\t>")); - view_menu->SetHelpString(OPJFRAME_VIEWMORERES, wxT("Increase the resolution")); - - view_menu->AppendSeparator(); - - view_menu->Append(OPJFRAME_VIEWPREVCOMP, wxT("&Prev component\tDown")); - view_menu->SetHelpString(OPJFRAME_VIEWPREVCOMP, wxT("View previous component")); - - view_menu->Append(OPJFRAME_VIEWALLCOMPS, wxT("&All components\ta")); - view_menu->SetHelpString(OPJFRAME_VIEWALLCOMPS, wxT("View all components")); - - view_menu->Append(OPJFRAME_VIEWNEXTCOMP, wxT("&Next component\tUp")); - view_menu->SetHelpString(OPJFRAME_VIEWNEXTCOMP, wxT("View next component")); - - - // settings menu and its items - wxMenu *sets_menu = new wxMenu; - - sets_menu->Append(OPJFRAME_SETSENCO, wxT("&Encoder\tCtrl+E")); - sets_menu->SetHelpString(OPJFRAME_SETSENCO, wxT("Encoder settings")); - - 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(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 - SetMenuBar(menu_bar); - - // the status bar - CreateStatusBar(); - - // the toolbar - tool_bar = new wxToolBar(this, OPJFRAME_TOOLBAR, - wxDefaultPosition, wxDefaultSize, - wxTB_HORIZONTAL | wxNO_BORDER); - wxBitmap bmpOpen = wxArtProvider::GetBitmap(wxART_FILE_OPEN, wxART_TOOLBAR, - wxDefaultSize); - wxBitmap bmpSaveAs = wxArtProvider::GetBitmap(wxART_FILE_SAVE_AS, wxART_TOOLBAR, - wxDefaultSize); - wxBitmap bmpZoom = wxArtProvider::GetBitmap(wxART_FIND, wxART_TOOLBAR, - wxDefaultSize); - wxBitmap bmpFit = wxArtProvider::GetBitmap(wxART_FIND_AND_REPLACE, wxART_TOOLBAR, - wxDefaultSize); - wxBitmap bmpReload = wxArtProvider::GetBitmap(wxART_EXECUTABLE_FILE, wxART_TOOLBAR, - wxDefaultSize); - wxBitmap bmpDecosettings = wxArtProvider::GetBitmap(wxART_REPORT_VIEW, wxART_TOOLBAR, - wxDefaultSize); - wxBitmap bmpEncosettings = wxArtProvider::GetBitmap(wxART_LIST_VIEW, wxART_TOOLBAR, - wxDefaultSize); - wxBitmap bmpPrevframe = wxArtProvider::GetBitmap(wxART_GO_BACK, wxART_TOOLBAR, - wxDefaultSize); - wxBitmap bmpHomeframe = wxArtProvider::GetBitmap(wxART_GO_HOME, wxART_TOOLBAR, - wxDefaultSize); - wxBitmap bmpNextframe = wxArtProvider::GetBitmap(wxART_GO_FORWARD, wxART_TOOLBAR, - wxDefaultSize); - wxBitmap bmpLesslayers = bmpPrevframe; - wxBitmap bmpAlllayers = wxArtProvider::GetBitmap(wxART_GO_TO_PARENT, wxART_TOOLBAR, - wxDefaultSize); - wxBitmap bmpMorelayers = bmpNextframe; - wxBitmap bmpLessres = bmpPrevframe; - wxBitmap bmpFullres = wxArtProvider::GetBitmap(wxART_GO_TO_PARENT, wxART_TOOLBAR, - wxDefaultSize); - wxBitmap bmpMoreres = bmpNextframe; - wxBitmap bmpPrevcomp = bmpPrevframe; - wxBitmap bmpAllcomps = wxArtProvider::GetBitmap(wxART_GO_TO_PARENT, wxART_TOOLBAR, - wxDefaultSize); - wxBitmap bmpNextcomp = bmpNextframe; - - tool_bar->AddTool(OPJFRAME_FILEOPEN, bmpOpen, wxT("Open")); - tool_bar->AddTool(OPJFRAME_FILESAVEAS, bmpSaveAs, wxT("Save as ")); - //tool_bar->EnableTool(OPJFRAME_FILESAVEAS, false); - tool_bar->AddSeparator(); - tool_bar->AddTool(OPJFRAME_VIEWZOOM, bmpZoom, wxT("Zoom")); - tool_bar->AddTool(OPJFRAME_VIEWFIT, bmpFit, wxT("Zoom to fit")); - tool_bar->AddTool(OPJFRAME_VIEWRELOAD, bmpReload, wxT("Reload")); - tool_bar->AddSeparator(); - tool_bar->AddTool(OPJFRAME_SETSDECO, bmpDecosettings, wxT("Decoder settings")); - tool_bar->AddTool(OPJFRAME_SETSENCO, bmpEncosettings, wxT("Encoder settings")); - tool_bar->AddSeparator(); - tool_bar->AddTool(OPJFRAME_VIEWPREVFRAME, bmpPrevframe, wxT("Previous frame")); - tool_bar->AddTool(OPJFRAME_VIEWHOMEFRAME, bmpHomeframe, wxT("Starting frame")); - tool_bar->AddTool(OPJFRAME_VIEWNEXTFRAME, bmpNextframe, wxT("Next frame")); - tool_bar->AddSeparator(); - tool_bar->AddTool(OPJFRAME_VIEWLESSLAYERS, bmpLesslayers, wxT("Remove a layer")); - tool_bar->AddTool(OPJFRAME_VIEWALLLAYERS, bmpAlllayers, wxT("Show all layers")); - tool_bar->AddTool(OPJFRAME_VIEWMORELAYERS, bmpMorelayers, wxT("Add a layer")); - tool_bar->AddSeparator(); - tool_bar->AddTool(OPJFRAME_VIEWLESSRES, bmpLessres, wxT("Reduce the resolution")); - tool_bar->AddTool(OPJFRAME_VIEWFULLRES, bmpFullres, wxT("Full resolution")); - tool_bar->AddTool(OPJFRAME_VIEWMORERES, bmpMoreres, wxT("Increase the resolution")); - tool_bar->AddSeparator(); - tool_bar->AddTool(OPJFRAME_VIEWPREVCOMP, bmpPrevcomp, wxT("Previous component")); - tool_bar->AddTool(OPJFRAME_VIEWALLCOMPS, bmpAllcomps, wxT("All components")); - tool_bar->AddTool(OPJFRAME_VIEWNEXTCOMP, bmpNextcomp, wxT("Next component")); - tool_bar->Realize(); - - // associate the toolbar with the frame - SetToolBar(tool_bar); - - // show the toolbar? - if (!wxGetApp().m_showtoolbar) - tool_bar->Show(false); - else - tool_bar->Show(true); - - // the logging window - loggingWindow = new wxSashLayoutWindow(this, OPJFRAME_LOGWIN, - wxDefaultPosition, wxSize(400, wxGetApp().m_peekerheight), - wxNO_BORDER | wxSW_3D | wxCLIP_CHILDREN - ); - loggingWindow->SetDefaultSize(wxSize(1000, wxGetApp().m_peekerheight)); - loggingWindow->SetOrientation(wxLAYOUT_HORIZONTAL); - loggingWindow->SetAlignment(wxLAYOUT_BOTTOM); - //loggingWindow->SetBackgroundColour(wxColour(0, 0, 255)); - loggingWindow->SetSashVisible(wxSASH_TOP, true); - - // show the logging? - if (!wxGetApp().m_showpeeker) - loggingWindow->Show(false); - else - loggingWindow->Show(true); - - // create the bottom notebook - m_bookCtrlbottom = new wxNotebook(loggingWindow, BOTTOM_NOTEBOOK_ID, - wxDefaultPosition, wxDefaultSize, - wxBK_LEFT); - - // create the text control of the logger - m_textCtrl = new wxTextCtrl(m_bookCtrlbottom, wxID_ANY, wxT(""), - wxDefaultPosition, wxDefaultSize, - wxTE_MULTILINE | wxSUNKEN_BORDER | wxTE_READONLY - ); - m_textCtrl->SetValue(_T("Logging window\n")); - - // add it to the notebook - m_bookCtrlbottom->AddPage(m_textCtrl, wxT("Log")); - - // 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_RICH - ); - 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"), false); - - // the browser window - markerTreeWindow = new wxSashLayoutWindow(this, OPJFRAME_BROWSEWIN, - wxDefaultPosition, wxSize(wxGetApp().m_browserwidth, 30), - wxNO_BORDER | wxSW_3D | wxCLIP_CHILDREN - ); - markerTreeWindow->SetDefaultSize(wxSize(wxGetApp().m_browserwidth, 1000)); - markerTreeWindow->SetOrientation(wxLAYOUT_VERTICAL); - markerTreeWindow->SetAlignment(wxLAYOUT_LEFT); - //markerTreeWindow->SetBackgroundColour(wxColour(0, 255, 0)); - markerTreeWindow->SetSashVisible(wxSASH_RIGHT, true); - markerTreeWindow->SetExtraBorderSize(0); - - // create the browser notebook - m_bookCtrl = new wxNotebook(markerTreeWindow, LEFT_NOTEBOOK_ID, - wxDefaultPosition, wxDefaultSize, - wxBK_TOP); - - // show the browser? - if (!wxGetApp().m_showbrowser) - markerTreeWindow->Show(false); - else - markerTreeWindow->Show(true); - -#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? - delete wxLog::SetActiveTarget(new wxLogStderr); -#else - // set our text control as the log target - wxLogTextCtrl *logWindow = new wxLogTextCtrl(m_textCtrl); - delete wxLog::SetActiveTarget(logWindow); -#endif - - // associate drop targets with the controls - SetDropTarget(new OPJDnDFile(this)); - -} - -// this is the frame destructor -OPJFrame::~OPJFrame(void) -{ - // save size settings - GetSize(&(wxGetApp().m_framewidth), &(wxGetApp().m_frameheight)); - - // delete all possible things - delete m_bookCtrl; - m_bookCtrl = NULL; - - delete markerTreeWindow; - markerTreeWindow = NULL; - - delete m_textCtrl; - m_textCtrl = NULL; - - delete m_bookCtrlbottom; - m_bookCtrlbottom = NULL; - - delete loggingWindow; - loggingWindow = NULL; -} - -void OPJFrame::OnNotebook(wxNotebookEvent& event) -{ - int sel = event.GetSelection(); - long childnum; - - m_bookCtrl->GetPageText(sel).ToLong(&childnum); - - if (m_childhash[childnum]) - m_childhash[childnum]->Activate(); - - //wxLogMessage(wxT("Selection changed (now %d --> %d)"), childnum, m_childhash[childnum]->m_winnumber); - -} - - -void OPJFrame::Resize(int number) -{ - wxSize size = GetClientSize(); -} - -void OPJFrame::OnSetsEnco(wxCommandEvent& event) -{ - int n; - - OPJEncoderDialog dialog(this, event.GetId()); - - if (dialog.ShowModal() == wxID_OK) { - - // load settings - wxGetApp().m_subsampling = dialog.m_subsamplingCtrl->GetValue(); - wxGetApp().m_origin = dialog.m_originCtrl->GetValue(); - wxGetApp().m_rates = dialog.m_rateCtrl->GetValue(); - wxGetApp().m_quality = dialog.m_qualityCtrl->GetValue(); - wxGetApp().m_enablequality = dialog.m_qualityRadio->GetValue(); - wxGetApp().m_multicomp = dialog.m_mctCheck->GetValue(); - wxGetApp().m_irreversible = dialog.m_irrevCheck->GetValue(); - wxGetApp().m_resolutions = dialog.m_resolutionsCtrl->GetValue(); - wxGetApp().m_cbsize = dialog.m_cbsizeCtrl->GetValue(); - wxGetApp().m_prsize = dialog.m_prsizeCtrl->GetValue(); - wxGetApp().m_tsize = dialog.m_tsizeCtrl->GetValue(); - wxGetApp().m_torigin = dialog.m_toriginCtrl->GetValue(); - wxGetApp().m_progression = dialog.progressionBox->GetSelection(); - wxGetApp().m_enablesop = dialog.m_sopCheck->GetValue(); - wxGetApp().m_enableeph = dialog.m_ephCheck->GetValue(); - wxGetApp().m_enablebypass = dialog.m_enablebypassCheck->GetValue(); - wxGetApp().m_enablereset = dialog.m_enableresetCheck->GetValue(); - wxGetApp().m_enablerestart = dialog.m_enablerestartCheck->GetValue(); - wxGetApp().m_enablevsc = dialog.m_enablevscCheck->GetValue(); - wxGetApp().m_enableerterm = dialog.m_enableertermCheck->GetValue(); - wxGetApp().m_enablesegmark = dialog.m_enablesegmarkCheck->GetValue(); - wxGetApp().m_enableidx = dialog.m_enableidxCheck->GetValue(); - wxGetApp().m_index = dialog.m_indexCtrl->GetValue(); - wxGetApp().m_enablecomm = dialog.m_enablecommCheck->GetValue(); - wxGetApp().m_comment = dialog.m_commentCtrl->GetValue(); - wxGetApp().m_enablepoc = dialog.m_enablepocCheck->GetValue(); - wxGetApp().m_poc = dialog.m_pocCtrl->GetValue(); -#ifdef USE_JPWL - wxGetApp().m_enablejpwle = dialog.m_enablejpwlCheck->GetValue(); - for (n = 0; n < MYJPWL_MAX_NO_TILESPECS; n++) { - wxGetApp().m_hprotsel[n] = dialog.m_hprotChoice[n]->GetSelection(); - wxGetApp().m_htileval[n] = dialog.m_htileCtrl[n]->GetValue(); - wxGetApp().m_pprotsel[n] = dialog.m_pprotChoice[n]->GetSelection(); - wxGetApp().m_ptileval[n] = dialog.m_ptileCtrl[n]->GetValue(); - wxGetApp().m_ppackval[n] = dialog.m_ppackCtrl[n]->GetValue(); - wxGetApp().m_sensisel[n] = dialog.m_sensiChoice[n]->GetSelection(); - wxGetApp().m_stileval[n] = dialog.m_stileCtrl[n]->GetValue(); - } -#endif // USE_JPWL - }; -} - -void OPJFrame::OnSetsDeco(wxCommandEvent& event) -{ - OPJDecoderDialog dialog(this, event.GetId()); - - if (dialog.ShowModal() == wxID_OK) { - - // load settings - wxGetApp().m_enabledeco = dialog.m_enabledecoCheck->GetValue(); - wxGetApp().m_enableparse = dialog.m_enableparseCheck->GetValue(); - wxGetApp().m_resizemethod = dialog.m_resizeBox->GetSelection() - 1; - wxGetApp().m_reducefactor = dialog.m_reduceCtrl->GetValue(); - wxGetApp().m_qualitylayers = dialog.m_layerCtrl->GetValue(); - wxGetApp().m_components = dialog.m_numcompsCtrl->GetValue(); - wxGetApp().m_framenum = dialog.m_framenumCtrl->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& event) -{ - OPJChildFrame *currchild; - wxString eventstring = event.GetString(); - - //wxLogMessage(wxT("OnFit:%d:%s"), event.GetInt(), eventstring); - - // current child - if (event.GetInt() >= 1) { - currchild = m_childhash[event.GetInt()]; - } else { - currchild = (OPJChildFrame *) GetActiveChild(); - } - - // problems - 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(-1, 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(); - - // resizing enabled? - if (wxGetApp().m_resizemethod == -1) { - - zooml = 100; - - } else { - - if (zooml < 0) { - // find a fit-to-width zoom - int wzooml, hzooml; - //wxSize clientsize = currframe->m_canvas->GetClientSize(); - wxSize clientsize = currframe->m_frame->GetActiveChild()->GetClientSize(); - wzooml = (int) floor(100.0 * (double) clientsize.GetWidth() / (double) (2 * OPJ_CANVAS_BORDER + currframe->m_canvas->m_image100.GetWidth())); - hzooml = (int) floor(100.0 * (double) clientsize.GetHeight() / (double) (2 * OPJ_CANVAS_BORDER + currframe->m_canvas->m_image100.GetHeight())); - zooml = wxMin(100, wxMin(wzooml, hzooml)); - } - } - - if (zooml != 100) - new_image.Rescale((int) ((double) zooml * (double) new_image.GetWidth() / 100.0), - (int) ((double) zooml * (double) new_image.GetHeight() / 100.0), - wxGetApp().m_resizemethod ? wxIMAGE_QUALITY_HIGH : 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(); - - wxLogMessage(wxT("Rescale said %d%%"), zooml); - - // update zoom - currframe->m_canvas->m_zooml = zooml; -} - - -void OPJFrame::OnReload(wxCommandEvent& event) -{ - OPJChildFrame *currframe = (OPJChildFrame *) GetActiveChild(); - - if (currframe) { - OPJDecoThread *dthread = currframe->m_canvas->CreateDecoThread(); - - if (dthread->Run() != wxTHREAD_NO_ERROR) - wxLogMessage(wxT("Can't start deco thread!")); - else - wxLogMessage(wxT("New deco thread started.")); - - currframe->m_canvas->Refresh(); - - // update zoom - //currframe->m_canvas->m_zooml = zooml; - } -} - -void OPJFrame::OnPrevFrame(wxCommandEvent& event) -{ - if (--wxGetApp().m_framenum < 0) - wxGetApp().m_framenum = 0; - - wxCommandEvent e; - OnReload(e); -} - -void OPJFrame::OnHomeFrame(wxCommandEvent& event) -{ - wxGetApp().m_framenum = 0; - - wxCommandEvent e; - OnReload(e); -} - -void OPJFrame::OnNextFrame(wxCommandEvent& event) -{ - ++wxGetApp().m_framenum; - - wxCommandEvent e; - OnReload(e); -} - -void OPJFrame::OnLessLayers(wxCommandEvent& event) -{ - if (--wxGetApp().m_qualitylayers < 1) - wxGetApp().m_qualitylayers = 1; - - wxCommandEvent e; - OnReload(e); -} - -void OPJFrame::OnAllLayers(wxCommandEvent& event) -{ - wxGetApp().m_qualitylayers = 0; - - wxCommandEvent e; - OnReload(e); -} - -void OPJFrame::OnMoreLayers(wxCommandEvent& event) -{ - ++wxGetApp().m_qualitylayers; - - wxCommandEvent e; - OnReload(e); -} - -void OPJFrame::OnLessRes(wxCommandEvent& event) -{ - ++wxGetApp().m_reducefactor; - - wxCommandEvent e; - OnReload(e); -} - -void OPJFrame::OnFullRes(wxCommandEvent& event) -{ - wxGetApp().m_reducefactor = 0; - - wxCommandEvent e; - OnReload(e); -} - -void OPJFrame::OnMoreRes(wxCommandEvent& event) -{ - if (--wxGetApp().m_reducefactor < 0) - wxGetApp().m_reducefactor = 0; - - wxCommandEvent e; - OnReload(e); -} - -void OPJFrame::OnPrevComp(wxCommandEvent& event) -{ - if (--wxGetApp().m_components < 1) - wxGetApp().m_components = 1; - - wxCommandEvent e; - OnReload(e); -} - -void OPJFrame::OnAllComps(wxCommandEvent& event) -{ - wxGetApp().m_components = 0; - - wxCommandEvent e; - OnReload(e); -} - -void OPJFrame::OnNextComp(wxCommandEvent& event) -{ - ++wxGetApp().m_components; - - wxCommandEvent e; - OnReload(e); -} - -void OPJFrame::OnToggleBrowser(wxCommandEvent& WXUNUSED(event)) -{ - if (markerTreeWindow->IsShown()) - markerTreeWindow->Show(false); - else - markerTreeWindow->Show(true); - - wxLayoutAlgorithm layout; - layout.LayoutMDIFrame(this); - - wxGetApp().m_showbrowser = markerTreeWindow->IsShown(); - - // Leaves bits of itself behind sometimes - GetClientWindow()->Refresh(); -} - -void OPJFrame::OnTogglePeeker(wxCommandEvent& WXUNUSED(event)) -{ - if (loggingWindow->IsShown()) - loggingWindow->Show(false); - else - loggingWindow->Show(true); - - wxLayoutAlgorithm layout; - layout.LayoutMDIFrame(this); - - wxGetApp().m_showpeeker = loggingWindow->IsShown(); - - // Leaves bits of itself behind sometimes - GetClientWindow()->Refresh(); -} - -void OPJFrame::OnToggleToolbar(wxCommandEvent& WXUNUSED(event)) -{ - if (tool_bar->IsShown()) - tool_bar->Show(false); - else - tool_bar->Show(true); - - wxLayoutAlgorithm layout; - layout.LayoutMDIFrame(this); - - wxGetApp().m_showtoolbar = tool_bar->IsShown(); - - // Leaves bits of itself behind sometimes - GetClientWindow()->Refresh(); -} - -void OPJFrame::OnSashDrag(wxSashEvent& event) -{ - int wid, hei; - - if (event.GetDragStatus() == wxSASH_STATUS_OUT_OF_RANGE) - return; - - 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; - } - } - - wxLayoutAlgorithm layout; - layout.LayoutMDIFrame(this); - - // Leaves bits of itself behind sometimes - GetClientWindow()->Refresh(); - - // update dimensions - markerTreeWindow->GetSize(&wid, &hei); - wxGetApp().m_browserwidth = wid; - - loggingWindow->GetSize(&wid, &hei); - wxGetApp().m_peekerheight = hei; - -} - -void OPJFrame::OnThreadLogmsg(wxCommandEvent& event) -{ -#if 1 - wxLogMessage(wxT("Frame got message from worker thread: %d"), event.GetInt()); - wxLogMessage(event.GetString()); -#else - int n = event.GetInt(); - if ( n == -1 ) - { - m_dlgProgress->Destroy(); - m_dlgProgress = (wxProgressDialog *)NULL; - - // the dialog is aborted because the event came from another thread, so - // we may need to wake up the main event loop for the dialog to be - // really closed - wxWakeUpIdle(); - } - else - { - if ( !m_dlgProgress->Update(n) ) - { - wxCriticalSectionLocker lock(m_critsectWork); - - m_cancelled = true; - } - } -#endif -} - - -// physically save the file -void OPJFrame::SaveFile(wxArrayString paths, wxArrayString filenames) -{ - size_t count = paths.GetCount(); - wxString msg, s; - - if (wxFile::Exists(paths[0].c_str())) { - - s.Printf(wxT("File %s already exists. Do you want to overwrite it?\n"), filenames[0].c_str()); - wxMessageDialog dialog3(this, s, _T("File exists"), wxYES_NO); - if (dialog3.ShowModal() == wxID_NO) - return; - } - - /*s.Printf(_T("File %d: %s (%s)\n"), (int)0, paths[0].c_str(), filenames[0].c_str()); - msg += s; - - wxMessageDialog dialog2(this, msg, _T("Selected files")); - dialog2.ShowModal();*/ - - if (!GetActiveChild()) - return; - - ((OPJChildFrame *) GetActiveChild())->m_canvas->m_savename = paths[0]; - - OPJEncoThread *ethread = ((OPJChildFrame *) GetActiveChild())->m_canvas->CreateEncoThread(); - - if (ethread->Run() != wxTHREAD_NO_ERROR) - wxLogMessage(wxT("Can't start enco thread!")); - else - wxLogMessage(wxT("New enco thread started.")); - - -} - -// physically open the files -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()); - - msg += s; - - /*wxMessageDialog dialog2(this, msg, _T("Selected files")); - dialog2.ShowModal();*/ - - // 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; - - // create own marker tree - m_treehash[winNumber] = new OPJMarkerTree(m_bookCtrl, subframe, 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); - - for (unsigned 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)) -{ - wxString wildcards = -#ifdef __WXMOTIF__ - wxT("JPEG 2000 files (*.jp2,*.j2k,*.j2c,*.mj2)|*.*j*2*"); -#else -#if wxUSE_LIBOPENJPEG - wxT("JPEG 2000 files (*.jp2,*.j2k,*.j2c,*.mj2)|*.jp2;*.j2k;*.j2c;*.mj2") -#endif -#if USE_MXF - wxT("|MXF JPEG 2000 video (*.mxf)|*.mxf") -#endif // USE_MXF -#if wxUSE_LIBJPEG - wxT("|JPEG files (*.jpg)|*.jpg") -#endif -#if OPJ_MANYFORMATS - wxT("|BMP files (*.bmp)|*.bmp") - wxT("|PNG files (*.png)|*.png") - wxT("|GIF files (*.gif)|*.gif") - wxT("|PNM files (*.pnm)|*.pnm") - wxT("|TIFF files (*.tif,*.tiff)|*.tif*") -#endif - wxT("|All files|*"); -#endif - wxFileDialog dialog(this, _T("Open image file(s)"), - wxEmptyString, wxEmptyString, wildcards, - wxFD_OPEN|wxFD_MULTIPLE); - - if (dialog.ShowModal() == wxID_OK) { - wxArrayString paths, filenames; - - dialog.GetPaths(paths); - dialog.GetFilenames(filenames); - - OpenFiles(paths, filenames); - } - -} - -void OPJFrame::OnFileSaveAs(wxCommandEvent& WXUNUSED(event)) -{ - wxString wildcards = -#ifdef wxUSE_LIBOPENJPEG -#ifdef __WXMOTIF__ - wxT("JPEG 2000 codestream (*.j2k)|*.*j*2*"); -#else - wxT("JPEG 2000 codestream (*.j2k)|*.j2k") - wxT("|JPEG 2000 file format (*.jp2)|*.jp2"); -#endif -#else - wxT("Houston we have a problem"); -#endif - - wxFileDialog dialog(this, _T("Save image file"), - wxEmptyString, wxEmptyString, wildcards, - wxFD_SAVE); - - if (dialog.ShowModal() == wxID_OK) { - wxArrayString paths, filenames; - - dialog.GetPaths(paths); - dialog.GetFilenames(filenames); - - SaveFile(paths, filenames); - } - - -} - -void OPJFrame::OnMemoryOpen(wxCommandEvent& WXUNUSED(event)) -{ - // do nothing - return; - - wxTextEntryDialog dialog(this, wxT("Memory HEX address range: start_address-stop_address"), - wxT("Decode a memory buffer"), - wxT("0x-0x"), - wxOK | wxCANCEL | wxCENTRE, - wxDefaultPosition); - - if (dialog.ShowModal() == wxID_OK) { - - } - -} - -BEGIN_EVENT_TABLE(OPJCanvas, wxScrolledWindow) - EVT_MOUSE_EVENTS(OPJCanvas::OnEvent) - EVT_MENU(OPJCANVAS_THREADSIGNAL, OPJCanvas::OnThreadSignal) -END_EVENT_TABLE() - -// Define a constructor for my canvas -OPJCanvas::OPJCanvas(wxFileName fname, wxWindow *parent, const wxPoint& pos, const wxSize& size) - : wxScrolledWindow(parent, wxID_ANY, pos, size, - wxSUNKEN_BORDER | wxNO_FULL_REPAINT_ON_RESIZE) -{ - SetBackgroundColour(OPJ_CANVAS_COLOUR); - - m_fname = fname; - m_childframe = (OPJChildFrame *) parent; - // 100% zoom - m_zooml = 100; - - - OPJDecoThread *dthread = CreateDecoThread(); - - if (dthread->Run() != wxTHREAD_NO_ERROR) - wxLogMessage(wxT("Can't start deco thread!")); - else - wxLogMessage(wxT("New deco thread started.")); - - // 100% zoom - //m_zooml = 100; - -} - -OPJDecoThread *OPJCanvas::CreateDecoThread(void) -{ - OPJDecoThread *dthread = new OPJDecoThread(this); - - if (dthread->Create() != wxTHREAD_NO_ERROR) - wxLogError(wxT("Can't create deco thread!")); - - wxCriticalSectionLocker enter(wxGetApp().m_deco_critsect); - wxGetApp().m_deco_threads.Add(dthread); - - return dthread; -} - -OPJEncoThread *OPJCanvas::CreateEncoThread(void) -{ - OPJEncoThread *ethread = new OPJEncoThread(this); - - if (ethread->Create() != wxTHREAD_NO_ERROR) - wxLogError(wxT("Can't create enco thread!")); - - wxCriticalSectionLocker enter(wxGetApp().m_enco_critsect); - wxGetApp().m_enco_threads.Add(ethread); - - return ethread; -} - -#define activeoverlay 0 -// Define the repainting behaviour -void OPJCanvas::OnDraw(wxDC& dc) -{ - if (m_image.Ok()) { - dc.DrawBitmap(m_image, OPJ_CANVAS_BORDER, OPJ_CANVAS_BORDER); - - if (activeoverlay) { - dc.SetPen(*wxRED_PEN); - dc.SetBrush(*wxTRANSPARENT_BRUSH); - //int tw, th; - dc.DrawRectangle(OPJ_CANVAS_BORDER, OPJ_CANVAS_BORDER, - (unsigned long int) (0.5 + (double) m_zooml * (double) m_childframe->m_twidth / 100.0), - (unsigned long int) (0.5 + (double) m_zooml * (double) m_childframe->m_theight / 100.0)); - } - - } else { - dc.SetFont(*wxSWISS_FONT); - dc.SetPen(*wxBLACK_PEN); -#ifdef __WXGTK__ - dc.DrawText(_T("Decoding image, please wait... (press \"Zoom to Fit\" to show the image)"), 40, 50); -#else - dc.DrawText(_T("Decoding image, please wait..."), 40, 50); -#endif - } -} - -// This implements a tiny doodling program! Drag the mouse using -// the left button. -void OPJCanvas::OnEvent(wxMouseEvent& event) -{ -#if USE_PENCIL_ON_CANVAS - wxClientDC dc(this); - PrepareDC(dc); - - wxPoint pt(event.GetLogicalPosition(dc)); - - if ((xpos > -1) && (ypos > -1) && event.Dragging()) { - dc.SetPen(*wxRED_PEN); - dc.DrawLine(xpos, ypos, pt.x, pt.y); - } - xpos = pt.x; - ypos = pt.y; -#endif -} - -void OPJFrame::OnSize(wxSizeEvent& WXUNUSED(event)) -{ - wxLayoutAlgorithm layout; - layout.LayoutMDIFrame(this); -} - -void OPJCanvas::OnThreadSignal(wxCommandEvent& event) -{ -#if 1 - wxLogMessage(wxT("Canvas got signal from deco thread: %d"), event.GetInt()); - wxLogMessage(event.GetString()); -#else - int n = event.GetInt(); - if ( n == -1 ) - { - m_dlgProgress->Destroy(); - m_dlgProgress = (wxProgressDialog *)NULL; - - // the dialog is aborted because the event came from another thread, so - // we may need to wake up the main event loop for the dialog to be - // really closed - wxWakeUpIdle(); - } - else - { - if ( !m_dlgProgress->Update(n) ) - { - wxCriticalSectionLocker lock(m_critsectWork); - - m_cancelled = true; - } - } -#endif -} - - -// Note that OPJFRAME_FILEOPEN and OPJFRAME_HELPABOUT commands get passed -// to the parent window for processing, so no need to -// duplicate event handlers here. - -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) -END_EVENT_TABLE() - -OPJChildFrame::OPJChildFrame(OPJFrame *parent, wxFileName fname, int winnumber, const wxString& title, const wxPoint& pos, const wxSize& size, -const long style): - wxMDIChildFrame(parent, wxID_ANY, title, pos, size, style) -{ - m_frame = (OPJFrame *) parent; - m_canvas = NULL; - //my_children.Append(this); - m_fname = fname; - m_winnumber = winnumber; - SetTitle(wxString::Format(_T("%d: "), m_winnumber) + m_fname.GetFullName()); - - // Give it an icon (this is ignored in MDI mode: uses resources) -#ifdef __WXMSW__ - SetIcon(wxIcon(wxT("OPJChild16"))); -#endif - - // Give it a status line - /*CreateStatusBar();*/ - - int width, height; - GetClientSize(&width, &height); - - OPJCanvas *canvas = new OPJCanvas(fname, this, wxPoint(0, 0), wxSize(width, height)); -#if USE_PENCIL_ON_CANVAS - canvas->SetCursor(wxCursor(wxCURSOR_PENCIL)); -#endif - m_canvas = canvas; - - // Give it scrollbars - canvas->SetScrollbars(20, 20, 5, 5); - - Show(true); - Maximize(true); - - /*wxLogError(wxString::Format(wxT("Created tree %d (0x%x)"), m_winnumber, m_frame->m_treehash[m_winnumber]));*/ - -} - -OPJChildFrame::~OPJChildFrame(void) -{ - //my_children.DeleteObject(this); -} - - -void OPJChildFrame::OnClose(wxCloseEvent& event) -{ - for (unsigned 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; - } - } - Destroy(); - - wxLogMessage(wxT("Closed: %d"), m_winnumber); -} - -void OPJChildFrame::OnActivate(wxActivateEvent& event) -{ - /*if (event.GetActive() && m_canvas) - m_canvas->SetFocus();*/ -} - -void OPJChildFrame::OnGotFocus(wxFocusEvent& event) -{ - // we need to check if the notebook is being destroyed or not - if (!m_frame->m_bookCtrl) - return; - - for (unsigned 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->ChangeSelection(p); - break; - } - - } - - //wxLogMessage(wxT("Got focus: %d (%x)"), m_winnumber, event.GetWindow()); -} - -void OPJChildFrame::OnLostFocus(wxFocusEvent& event) -{ - //wxLogMessage(wxT("Lost focus: %d (%x)"), m_winnumber, event.GetWindow()); -} - - -//////////////////////////////// -// drag and drop -//////////////////////////////// - -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; -} - +/* + * Copyright (c) 2007, Digital Signal Processing Laboratory, Universita' degli studi di Perugia (UPG), Italy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are 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. + */ +///////////////////////////////////////////////////////////////////////////// +// Name: sashtest.cpp +// Purpose: Layout/sash sample +// Author: Julian Smart +// Modified by: +// Created: 04/01/98 +// RCS-ID: $Id: sashtest.cpp,v 1.18 2005/08/23 15:54:35 ABX Exp $ +// Copyright: (c) Julian Smart +// Licence: wxWindows license +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// +// Name: treetest.cpp +// Purpose: wxTreeCtrl sample +// Author: Julian Smart +// Modified by: +// Created: 04/01/98 +// RCS-ID: $Id: treetest.cpp,v 1.110 2006/11/04 11:26:51 VZ Exp $ +// Copyright: (c) Julian Smart +// Licence: wxWindows license +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// +// 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: thread.cpp +// Purpose: wxWidgets thread sample +// Author: Guilhem Lavaux, Vadim Zeitlin +// Modified by: +// Created: 06/16/98 +// RCS-ID: $Id: thread.cpp,v 1.26 2006/10/02 05:36:28 PC Exp $ +// Copyright: (c) 1998-2002 wxWidgets team +// Licence: wxWindows license +///////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +// Name: samples/image/image.cpp +// Purpose: sample showing operations with wxImage +// Author: Robert Roebling +// Modified by: +// Created: 1998 +// RCS-ID: $Id: image.cpp,v 1.120 2006/12/06 17:13:11 VZ Exp $ +// Copyright: (c) 1998-2005 Robert Roebling +// License: wxWindows licence +/////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// +// Name: samples/console/console.cpp +// Purpose: A sample console (as opposed to GUI) program using wxWidgets +// Author: Vadim Zeitlin +// Modified by: +// Created: 04.10.99 +// RCS-ID: $Id: console.cpp,v 1.206 2006/11/12 19:55:19 VZ Exp $ +// Copyright: (c) 1999 Vadim Zeitlin +// Licence: wxWindows license +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// +// Name: samples/notebook/notebook.cpp +// Purpose: a sample demonstrating notebook usage +// Author: Julian Smart +// Modified by: Dimitri Schoolwerth +// Created: 26/10/98 +// RCS-ID: $Id: notebook.cpp,v 1.49 2006/11/04 18:24:07 RR Exp $ +// Copyright: (c) 1998-2002 wxWidgets team +// License: wxWindows license +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// +// 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 +///////////////////////////////////////////////////////////////////////////// + + +#include "OPJViewer.h" + +IMPLEMENT_APP(OPJViewerApp) + +// For drawing lines in a canvas +long xpos = -1; +long ypos = -1; + +int winNumber = 1; + +// Initialise this in OnInit, not statically +bool OPJViewerApp::OnInit(void) +{ + int n; +#if wxUSE_UNICODE + + wxChar **wxArgv = new wxChar *[argc + 1]; + + for (n = 0; n < argc; n++ ) { + wxMB2WXbuf warg = wxConvertMB2WX((char *) 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_PARAM, NULL, NULL, _T("input file"), + wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL | wxCMD_LINE_PARAM_MULTIPLE }, + + { wxCMD_LINE_NONE } + }; + + wxCmdLineParser parser(cmdLineDesc, argc, wxArgv); + + switch (parser.Parse()) { + case -1: + wxLogMessage(wxT("Help was given, terminating.")); + break; + + case 0: + ShowCmdLine(parser); + break; + + default: + wxLogMessage(wxT("Syntax error detected.")); + break; + } + +#endif // wxUSE_CMDLINE_PARSER + + //wxInitAllImageHandlers(); +#if wxUSE_LIBJPEG + wxImage::AddHandler( new wxJPEGHandler ); +#endif +#if wxUSE_LIBOPENJPEG + wxImage::AddHandler( new wxJPEG2000Handler ); +#endif +#if USE_MXF + wxImage::AddHandler( new wxMXFHandler ); +#endif // USE_MXF +#if OPJ_MANYFORMATS + wxImage::AddHandler( new wxBMPHandler ); + wxImage::AddHandler( new wxPNGHandler ); + wxImage::AddHandler( new wxGIFHandler ); + wxImage::AddHandler( new wxPNMHandler ); + wxImage::AddHandler( new wxTIFFHandler ); +#endif + // we use a XPM image in our HTML page + wxImage::AddHandler(new wxXPMHandler); + + // memory file system + wxFileSystem::AddHandler(new wxMemoryFSHandler); + +#ifdef OPJ_INICONFIG + //load decoding engine parameters + OPJconfig = new wxConfig(OPJ_APPLICATION, OPJ_APPLICATION_VENDOR); + + OPJconfig->Read(wxT("decode/enabledeco"), &m_enabledeco, (bool) true); + OPJconfig->Read(wxT("decode/enableparse"), &m_enableparse, (bool) true); + OPJconfig->Read(wxT("decode/resizemethod"), &m_resizemethod, (long) 0); + OPJconfig->Read(wxT("decode/xxxreducefactor"), &m_reducefactor, (long) 0); + OPJconfig->Read(wxT("decode/xxxqualitylayers"), &m_qualitylayers, (long) 0); + OPJconfig->Read(wxT("decode/xxxcomponents"), &m_components, (long) 0); + OPJconfig->Read(wxT("decode/xxxframenum"), &m_framenum, (long) 0); +#ifdef USE_JPWL + OPJconfig->Read(wxT("decode/enablejpwl"), &m_enablejpwl, (bool) true); + OPJconfig->Read(wxT("decode/expcomps"), &m_expcomps, (long) JPWL_EXPECTED_COMPONENTS); + OPJconfig->Read(wxT("decode/maxtiles"), &m_maxtiles, (long) JPWL_MAXIMUM_TILES); +#endif // USE_JPWL + + OPJconfig->Write(wxT("teststring"), wxT("This is a test value")); + OPJconfig->Write(wxT("testbool"), (bool) true); + OPJconfig->Write(wxT("testlong"), (long) 245); + + OPJconfig->Read(wxT("showtoolbar"), &m_showtoolbar, (bool) true); + OPJconfig->Read(wxT("showbrowser"), &m_showbrowser, (bool) true); + OPJconfig->Read(wxT("showpeeker"), &m_showpeeker, (bool) true); + OPJconfig->Read(wxT("browserwidth"), &m_browserwidth, (long) OPJ_BROWSER_WIDTH); + OPJconfig->Read(wxT("peekerheight"), &m_peekerheight, (long) OPJ_PEEKER_HEIGHT); + OPJconfig->Read(wxT("framewidth"), &m_framewidth, (long) OPJ_FRAME_WIDTH); + OPJconfig->Read(wxT("frameheight"), &m_frameheight, (long) OPJ_FRAME_HEIGHT); + + // load encoding engine parameters + OPJconfig->Read(wxT("encode/subsampling"), &m_subsampling, (wxString) wxT("1,1")); + OPJconfig->Read(wxT("encode/origin"), &m_origin, (wxString) wxT("0,0")); + OPJconfig->Read(wxT("encode/rates"), &m_rates, (wxString) wxT("20,10,5")); + OPJconfig->Read(wxT("encode/quality"), &m_quality, (wxString) wxT("30,35,40")); + OPJconfig->Read(wxT("encode/enablequality"), &m_enablequality, (bool) false); + OPJconfig->Read(wxT("encode/multicomp"), &m_multicomp, (bool) false); + OPJconfig->Read(wxT("encode/irreversible"), &m_irreversible, (bool) false); + OPJconfig->Read(wxT("encode/resolutions"), &m_resolutions, (int) 6); + OPJconfig->Read(wxT("encode/progression"), &m_progression, (int) 0); + OPJconfig->Read(wxT("encode/cbsize"), &m_cbsize, (wxString) wxT("32,32")); + OPJconfig->Read(wxT("encode/prsize"), &m_prsize, (wxString) wxT("[128,128],[128,128]")); + OPJconfig->Read(wxT("encode/tsize"), &m_tsize, (wxString) wxT("")); + OPJconfig->Read(wxT("encode/torigin"), &m_torigin, (wxString) wxT("0,0")); + OPJconfig->Read(wxT("encode/enablesop"), &m_enablesop, (bool) false); + OPJconfig->Read(wxT("encode/enableeph"), &m_enableeph, (bool) false); + OPJconfig->Read(wxT("encode/enablebypass"), &m_enablebypass, (bool) false); + OPJconfig->Read(wxT("encode/enablereset"), &m_enablereset, (bool) false); + OPJconfig->Read(wxT("encode/enablerestart"), &m_enablerestart, (bool) false); + OPJconfig->Read(wxT("encode/enablevsc"), &m_enablevsc, (bool) false); + OPJconfig->Read(wxT("encode/enableerterm"), &m_enableerterm, (bool) false); + OPJconfig->Read(wxT("encode/enablesegmark"), &m_enablesegmark, (bool) false); + OPJconfig->Read(wxT("encode/enablecomm"), &m_enablecomm, (bool) true); + OPJconfig->Read(wxT("encode/enablepoc"), &m_enablepoc, (bool) false); + OPJconfig->Read(wxT("encode/comment"), &m_comment, (wxString) wxT("")); + OPJconfig->Read(wxT("encode/poc"), &m_poc, (wxString) wxT("T1=0,0,1,5,3,CPRL/T1=5,0,1,6,3,CPRL")); + OPJconfig->Read(wxT("encode/enableidx"), &m_enableidx, (bool) false); + OPJconfig->Read(wxT("encode/index"), &m_index, (wxString) wxT("index.txt")); +#ifdef USE_JPWL + OPJconfig->Read(wxT("encode/enablejpwl"), &m_enablejpwle, (bool) true); + for (n = 0; n < MYJPWL_MAX_NO_TILESPECS; n++) { + OPJconfig->Read(wxT("encode/jpwl/hprotsel") + wxString::Format(wxT("%02d"), n), &m_hprotsel[n], 0); + OPJconfig->Read(wxT("encode/jpwl/htileval") + wxString::Format(wxT("%02d"), n), &m_htileval[n], 0); + OPJconfig->Read(wxT("encode/jpwl/pprotsel") + wxString::Format(wxT("%02d"), n), &m_pprotsel[n], 0); + OPJconfig->Read(wxT("encode/jpwl/ptileval") + wxString::Format(wxT("%02d"), n), &m_ptileval[n], 0); + OPJconfig->Read(wxT("encode/jpwl/ppackval") + wxString::Format(wxT("%02d"), n), &m_ppackval[n], 0); + OPJconfig->Read(wxT("encode/jpwl/sensisel") + wxString::Format(wxT("%02d"), n), &m_sensisel[n], 0); + OPJconfig->Read(wxT("encode/jpwl/stileval") + wxString::Format(wxT("%02d"), n), &m_stileval[n], 0); + } +#endif // USE_JPWL + +#else + // set decoding engine parameters + m_enabledeco = true; + m_enableparse = true; + m_resizemethod = 0; + m_reducefactor = 0; + m_qualitylayers = 0; + m_components = 0; + m_framenum = 0; +#ifdef USE_JPWL + m_enablejpwl = true; + m_expcomps = JPWL_EXPECTED_COMPONENTS; + m_maxtiles = JPWL_MAXIMUM_TILES; +#endif // USE_JPWL + m_showtoolbar = true; + m_showbrowser = true; + m_showpeeker = true; + m_browserwidth = OPJ_BROWSER_WIDTH; + m_peekerheight = OPJ_PEEKER_HEIGHT; + m_framewidth = OPJ_FRAME_WIDTH; + m_frameheight = OPJ_FRAME_HEIGHT; + + // set encoding engine parameters + m_subsampling = wxT("1,1"); + m_origin = wxT("0,0"); + m_rates = wxT("20,10,5"); + m_quality = wxT("30,35,40"); + m_enablequality = false; + m_multicomp = false; + m_irreversible = false; + m_resolutions = 6; + m_progression = 0; + m_cbsize= wxT("32,32"); + m_prsize= wxT("[128,128],[128,128]"); + m_tsize = wxT(""); + m_torigin = wxT("0,0"); + m_enablesop = false; + m_enableeph = false; + m_enablebypass = false; + m_enablereset = false; + m_enablerestart = false; + m_enablevsc = false; + m_enableerterm = false; + m_enablesegmark = false; + m_enableidx = false; + m_index = wxT("index.txt"); + m_enablecomm = true; + m_comment = wxT(""); + m_enablepoc = false; + m_poc = wxT("T1=0,0,1,5,3,CPRL/T1=5,0,1,6,3,CPRL"); +#ifdef USE_JPWL + m_enablejpwle = true; + for (n = 0; n < MYJPWL_MAX_NO_TILESPECS; n++) { + m_hprotsel[n] = 0; + m_htileval[n] = 0; + m_pprotsel[n] = 0; + m_ptileval[n] = 0; + m_sensisel[n] = 0; + m_stileval[n] = 0; + } +#endif // USE_JPWL + +#endif // OPJ_INICONFIG + + if (m_comment == wxT("")) { +#if defined __WXMSW__ + m_comment = wxT("Created by OPJViewer Win32 - OpenJPEG version "); +#elif defined __WXGTK__ + m_comment = wxT("Created by OPJViewer Lin32 - OpenJPEG version "); +#else + m_comment = wxT("Created by OPJViewer - OpenJPEG version "); +#endif + +#ifdef USE_JPWL + m_comment += wxString::Format(wxT("%s with JPWL"), (char *) opj_version()); +#else + m_comment += wxString::Format(wxT("%s"), (char *) opj_version()); +#endif + } + + // Create the main frame window + OPJFrame *frame = new OPJFrame(NULL, wxID_ANY, OPJ_APPLICATION_TITLEBAR, + wxDefaultPosition, wxSize(wxGetApp().m_framewidth, wxGetApp().m_frameheight), + 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(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 (unsigned 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; +} + +int OPJViewerApp::OnExit() +{ + int n; + +#ifdef OPJ_INICONFIG + OPJconfig->Write(wxT("decode/enabledeco"), m_enabledeco); + OPJconfig->Write(wxT("decode/enableparse"), m_enableparse); + OPJconfig->Write(wxT("decode/resizemethod"), m_resizemethod); + OPJconfig->Write(wxT("decode/reducefactor"), m_reducefactor); + OPJconfig->Write(wxT("decode/qualitylayers"), m_qualitylayers); + OPJconfig->Write(wxT("decode/components"), m_components); + OPJconfig->Write(wxT("decode/framenum"), m_framenum); +#ifdef USE_JPWL + OPJconfig->Write(wxT("decode/enablejpwl"), m_enablejpwl); + OPJconfig->Write(wxT("decode/expcomps"), m_expcomps); + OPJconfig->Write(wxT("decode/maxtiles"), m_maxtiles); +#endif // USE_JPWL + OPJconfig->Write(wxT("showtoolbar"), m_showtoolbar); + OPJconfig->Write(wxT("showbrowser"), m_showbrowser); + OPJconfig->Write(wxT("showpeeker"), m_showpeeker); + OPJconfig->Write(wxT("browserwidth"), m_browserwidth); + OPJconfig->Write(wxT("peekerheight"), m_peekerheight); + OPJconfig->Write(wxT("framewidth"), m_framewidth); + OPJconfig->Write(wxT("frameheight"), m_frameheight); + + OPJconfig->Write(wxT("encode/subsampling"), m_subsampling); + OPJconfig->Write(wxT("encode/origin"), m_origin); + OPJconfig->Write(wxT("encode/rates"), m_rates); + OPJconfig->Write(wxT("encode/quality"), m_quality); + OPJconfig->Write(wxT("encode/enablequality"), m_enablequality); + OPJconfig->Write(wxT("encode/multicomp"), m_multicomp); + OPJconfig->Write(wxT("encode/irreversible"), m_irreversible); + OPJconfig->Write(wxT("encode/resolutions"), m_resolutions); + OPJconfig->Write(wxT("encode/progression"), m_progression); + OPJconfig->Write(wxT("encode/cbsize"), m_cbsize); + OPJconfig->Write(wxT("encode/prsize"), m_prsize); + OPJconfig->Write(wxT("encode/tiles"), m_tsize); + OPJconfig->Write(wxT("encode/torigin"), m_torigin); + OPJconfig->Write(wxT("encode/enablesop"), m_enablesop); + OPJconfig->Write(wxT("encode/enableeph"), m_enableeph); + OPJconfig->Write(wxT("encode/enablebypass"), m_enablebypass); + OPJconfig->Write(wxT("encode/enablereset"), m_enablereset); + OPJconfig->Write(wxT("encode/enablerestart"), m_enablerestart); + OPJconfig->Write(wxT("encode/enablevsc"), m_enablevsc); + OPJconfig->Write(wxT("encode/enableerterm"), m_enableerterm); + OPJconfig->Write(wxT("encode/enablesegmark"), m_enablesegmark); + OPJconfig->Write(wxT("encode/enableidx"), m_enableidx); + OPJconfig->Write(wxT("encode/index"), m_index); + OPJconfig->Write(wxT("encode/enablecomm"), m_enablecomm); + OPJconfig->Write(wxT("encode/comment"), m_comment); + OPJconfig->Write(wxT("encode/enablepoc"), m_enablepoc); + OPJconfig->Write(wxT("encode/poc"), m_poc); +#ifdef USE_JPWL + OPJconfig->Write(wxT("encode/enablejpwl"), m_enablejpwle); + for (n = 0; n < MYJPWL_MAX_NO_TILESPECS; n++) { + OPJconfig->Write(wxT("encode/jpwl/hprotsel") + wxString::Format(wxT("%02d"), n), m_hprotsel[n]); + OPJconfig->Write(wxT("encode/jpwl/htileval") + wxString::Format(wxT("%02d"), n), m_htileval[n]); + OPJconfig->Write(wxT("encode/jpwl/pprotsel") + wxString::Format(wxT("%02d"), n), m_pprotsel[n]); + OPJconfig->Write(wxT("encode/jpwl/ptileval") + wxString::Format(wxT("%02d"), n), m_ptileval[n]); + OPJconfig->Write(wxT("encode/jpwl/ppackval") + wxString::Format(wxT("%02d"), n), m_ppackval[n]); + OPJconfig->Write(wxT("encode/jpwl/sensisel") + wxString::Format(wxT("%02d"), n), m_sensisel[n]); + OPJconfig->Write(wxT("encode/jpwl/stileval") + wxString::Format(wxT("%02d"), n), m_stileval[n]); + } +#endif // USE_JPWL + +#endif // OPJ_INICONFIG + + return 1; +} + +void OPJViewerApp::ShowCmdLine(const wxCmdLineParser& parser) +{ + wxString s = wxT("Command line parsed successfully:\nInput files: "); + + size_t count = parser.GetParamCount(); + for (size_t param = 0; param < count; param++) { + s << parser.GetParam(param) << ';'; + m_filelist.Add(parser.GetParam(param)); + } + + //wxLogMessage(s); +} + +// OPJFrame events + +// Event class for sending text messages between worker and GUI threads +BEGIN_EVENT_TABLE(OPJFrame, wxMDIParentFrame) + EVT_MENU(OPJFRAME_HELPABOUT, OPJFrame::OnAbout) + EVT_MENU(OPJFRAME_FILEOPEN, OPJFrame::OnFileOpen) + EVT_MENU(OPJFRAME_FILESAVEAS, OPJFrame::OnFileSaveAs) + EVT_MENU(OPJFRAME_MEMORYOPEN, OPJFrame::OnMemoryOpen) + EVT_SIZE(OPJFrame::OnSize) + 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_VIEWRELOAD, OPJFrame::OnReload) + EVT_MENU(OPJFRAME_VIEWPREVFRAME, OPJFrame::OnPrevFrame) + EVT_MENU(OPJFRAME_VIEWHOMEFRAME, OPJFrame::OnHomeFrame) + EVT_MENU(OPJFRAME_VIEWNEXTFRAME, OPJFrame::OnNextFrame) + EVT_MENU(OPJFRAME_VIEWLESSLAYERS, OPJFrame::OnLessLayers) + EVT_MENU(OPJFRAME_VIEWALLLAYERS, OPJFrame::OnAllLayers) + EVT_MENU(OPJFRAME_VIEWMORELAYERS, OPJFrame::OnMoreLayers) + EVT_MENU(OPJFRAME_VIEWLESSRES, OPJFrame::OnLessRes) + EVT_MENU(OPJFRAME_VIEWFULLRES, OPJFrame::OnFullRes) + EVT_MENU(OPJFRAME_VIEWMORERES, OPJFrame::OnMoreRes) + EVT_MENU(OPJFRAME_VIEWPREVCOMP, OPJFrame::OnPrevComp) + EVT_MENU(OPJFRAME_VIEWALLCOMPS, OPJFrame::OnAllComps) + EVT_MENU(OPJFRAME_VIEWNEXTCOMP, OPJFrame::OnNextComp) + EVT_MENU(OPJFRAME_FILETOGGLEB, OPJFrame::OnToggleBrowser) + EVT_MENU(OPJFRAME_FILETOGGLEP, OPJFrame::OnTogglePeeker) + EVT_MENU(OPJFRAME_FILETOGGLET, OPJFrame::OnToggleToolbar) + EVT_MENU(OPJFRAME_SETSENCO, OPJFrame::OnSetsEnco) + 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) + EVT_MENU(OPJFRAME_THREADLOGMSG, OPJFrame::OnThreadLogmsg) +END_EVENT_TABLE() + +// this is the frame constructor +OPJFrame::OPJFrame(wxWindow *parent, const wxWindowID id, const wxString& title, + const wxPoint& pos, const wxSize& size, const long style) + : wxMDIParentFrame(parent, id, title, pos, size, style) +{ + // file menu and its items + wxMenu *file_menu = new wxMenu; + + file_menu->Append(OPJFRAME_FILEOPEN, wxT("&Open\tCtrl+O")); + file_menu->SetHelpString(OPJFRAME_FILEOPEN, wxT("Open one or more files")); + + file_menu->Append(OPJFRAME_MEMORYOPEN, wxT("&Memory\tCtrl+M")); + file_menu->SetHelpString(OPJFRAME_MEMORYOPEN, wxT("Open a memory buffer")); + + file_menu->Append(OPJFRAME_FILECLOSE, wxT("&Close\tCtrl+C")); + file_menu->SetHelpString(OPJFRAME_FILECLOSE, wxT("Close current image")); + + file_menu->AppendSeparator(); + + file_menu->Append(OPJFRAME_FILESAVEAS, wxT("&Save as\tCtrl+S")); + file_menu->SetHelpString(OPJFRAME_FILESAVEAS, wxT("Save the current image")); + //file_menu->Enable(OPJFRAME_FILESAVEAS, false); + + file_menu->AppendSeparator(); + + file_menu->Append(OPJFRAME_FILETOGGLEB, wxT("Toggle &browser\tCtrl+B")); + file_menu->SetHelpString(OPJFRAME_FILETOGGLEB, wxT("Toggle the left browsing pane")); + + file_menu->Append(OPJFRAME_FILETOGGLEP, wxT("Toggle &peeker\tCtrl+P")); + file_menu->SetHelpString(OPJFRAME_FILETOGGLEP, wxT("Toggle the bottom peeking pane")); + + file_menu->Append(OPJFRAME_FILETOGGLET, wxT("Toggle &toolbar\tCtrl+T")); + file_menu->SetHelpString(OPJFRAME_FILETOGGLET, wxT("Toggle the toolbar")); + + file_menu->AppendSeparator(); + + 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")); + + view_menu->Append(OPJFRAME_VIEWRELOAD, wxT("&Reload image\tCtrl+R")); + view_menu->SetHelpString(OPJFRAME_VIEWRELOAD, wxT("Reload the current image")); + + view_menu->AppendSeparator(); + + view_menu->Append(OPJFRAME_VIEWPREVFRAME, wxT("&Prev frame\tLeft")); + view_menu->SetHelpString(OPJFRAME_VIEWPREVFRAME, wxT("View previous frame")); + + view_menu->Append(OPJFRAME_VIEWHOMEFRAME, wxT("&Start frame\tHome")); + view_menu->SetHelpString(OPJFRAME_VIEWHOMEFRAME, wxT("View starting frame")); + + view_menu->Append(OPJFRAME_VIEWNEXTFRAME, wxT("&Next frame\tRight")); + view_menu->SetHelpString(OPJFRAME_VIEWNEXTFRAME, wxT("View next frame")); + + view_menu->AppendSeparator(); + + view_menu->Append(OPJFRAME_VIEWLESSLAYERS, wxT("&Less layers\t-")); + view_menu->SetHelpString(OPJFRAME_VIEWLESSLAYERS, wxT("Remove a layer")); + + view_menu->Append(OPJFRAME_VIEWALLLAYERS, wxT("&All layers\t0")); + view_menu->SetHelpString(OPJFRAME_VIEWALLLAYERS, wxT("Show all layers")); + + view_menu->Append(OPJFRAME_VIEWMORELAYERS, wxT("&More layers\t+")); + view_menu->SetHelpString(OPJFRAME_VIEWMORELAYERS, wxT("Add a layer")); + + view_menu->AppendSeparator(); + + view_menu->Append(OPJFRAME_VIEWLESSRES, wxT("&Less resolution\t<")); + view_menu->SetHelpString(OPJFRAME_VIEWLESSRES, wxT("Reduce the resolution")); + + view_menu->Append(OPJFRAME_VIEWFULLRES, wxT("&Full resolution\tf")); + view_menu->SetHelpString(OPJFRAME_VIEWFULLRES, wxT("Full resolution")); + + view_menu->Append(OPJFRAME_VIEWMORERES, wxT("&More resolution\t>")); + view_menu->SetHelpString(OPJFRAME_VIEWMORERES, wxT("Increase the resolution")); + + view_menu->AppendSeparator(); + + view_menu->Append(OPJFRAME_VIEWPREVCOMP, wxT("&Prev component\tDown")); + view_menu->SetHelpString(OPJFRAME_VIEWPREVCOMP, wxT("View previous component")); + + view_menu->Append(OPJFRAME_VIEWALLCOMPS, wxT("&All components\ta")); + view_menu->SetHelpString(OPJFRAME_VIEWALLCOMPS, wxT("View all components")); + + view_menu->Append(OPJFRAME_VIEWNEXTCOMP, wxT("&Next component\tUp")); + view_menu->SetHelpString(OPJFRAME_VIEWNEXTCOMP, wxT("View next component")); + + + // settings menu and its items + wxMenu *sets_menu = new wxMenu; + + sets_menu->Append(OPJFRAME_SETSENCO, wxT("&Encoder\tCtrl+E")); + sets_menu->SetHelpString(OPJFRAME_SETSENCO, wxT("Encoder settings")); + + 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(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 + SetMenuBar(menu_bar); + + // the status bar + CreateStatusBar(); + + // the toolbar + tool_bar = new wxToolBar(this, OPJFRAME_TOOLBAR, + wxDefaultPosition, wxDefaultSize, + wxTB_HORIZONTAL | wxNO_BORDER); + wxBitmap bmpOpen = wxArtProvider::GetBitmap(wxART_FILE_OPEN, wxART_TOOLBAR, + wxDefaultSize); + wxBitmap bmpSaveAs = wxArtProvider::GetBitmap(wxART_FILE_SAVE_AS, wxART_TOOLBAR, + wxDefaultSize); + wxBitmap bmpZoom = wxArtProvider::GetBitmap(wxART_FIND, wxART_TOOLBAR, + wxDefaultSize); + wxBitmap bmpFit = wxArtProvider::GetBitmap(wxART_FIND_AND_REPLACE, wxART_TOOLBAR, + wxDefaultSize); + wxBitmap bmpReload = wxArtProvider::GetBitmap(wxART_EXECUTABLE_FILE, wxART_TOOLBAR, + wxDefaultSize); + wxBitmap bmpDecosettings = wxArtProvider::GetBitmap(wxART_REPORT_VIEW, wxART_TOOLBAR, + wxDefaultSize); + wxBitmap bmpEncosettings = wxArtProvider::GetBitmap(wxART_LIST_VIEW, wxART_TOOLBAR, + wxDefaultSize); + wxBitmap bmpPrevframe = wxArtProvider::GetBitmap(wxART_GO_BACK, wxART_TOOLBAR, + wxDefaultSize); + wxBitmap bmpHomeframe = wxArtProvider::GetBitmap(wxART_GO_HOME, wxART_TOOLBAR, + wxDefaultSize); + wxBitmap bmpNextframe = wxArtProvider::GetBitmap(wxART_GO_FORWARD, wxART_TOOLBAR, + wxDefaultSize); + wxBitmap bmpLesslayers = bmpPrevframe; + wxBitmap bmpAlllayers = wxArtProvider::GetBitmap(wxART_GO_TO_PARENT, wxART_TOOLBAR, + wxDefaultSize); + wxBitmap bmpMorelayers = bmpNextframe; + wxBitmap bmpLessres = bmpPrevframe; + wxBitmap bmpFullres = wxArtProvider::GetBitmap(wxART_GO_TO_PARENT, wxART_TOOLBAR, + wxDefaultSize); + wxBitmap bmpMoreres = bmpNextframe; + wxBitmap bmpPrevcomp = bmpPrevframe; + wxBitmap bmpAllcomps = wxArtProvider::GetBitmap(wxART_GO_TO_PARENT, wxART_TOOLBAR, + wxDefaultSize); + wxBitmap bmpNextcomp = bmpNextframe; + + tool_bar->AddTool(OPJFRAME_FILEOPEN, bmpOpen, wxT("Open")); + tool_bar->AddTool(OPJFRAME_FILESAVEAS, bmpSaveAs, wxT("Save as ")); + //tool_bar->EnableTool(OPJFRAME_FILESAVEAS, false); + tool_bar->AddSeparator(); + tool_bar->AddTool(OPJFRAME_VIEWZOOM, bmpZoom, wxT("Zoom")); + tool_bar->AddTool(OPJFRAME_VIEWFIT, bmpFit, wxT("Zoom to fit")); + tool_bar->AddTool(OPJFRAME_VIEWRELOAD, bmpReload, wxT("Reload")); + tool_bar->AddSeparator(); + tool_bar->AddTool(OPJFRAME_SETSDECO, bmpDecosettings, wxT("Decoder settings")); + tool_bar->AddTool(OPJFRAME_SETSENCO, bmpEncosettings, wxT("Encoder settings")); + tool_bar->AddSeparator(); + tool_bar->AddTool(OPJFRAME_VIEWPREVFRAME, bmpPrevframe, wxT("Previous frame")); + tool_bar->AddTool(OPJFRAME_VIEWHOMEFRAME, bmpHomeframe, wxT("Starting frame")); + tool_bar->AddTool(OPJFRAME_VIEWNEXTFRAME, bmpNextframe, wxT("Next frame")); + tool_bar->AddSeparator(); + tool_bar->AddTool(OPJFRAME_VIEWLESSLAYERS, bmpLesslayers, wxT("Remove a layer")); + tool_bar->AddTool(OPJFRAME_VIEWALLLAYERS, bmpAlllayers, wxT("Show all layers")); + tool_bar->AddTool(OPJFRAME_VIEWMORELAYERS, bmpMorelayers, wxT("Add a layer")); + tool_bar->AddSeparator(); + tool_bar->AddTool(OPJFRAME_VIEWLESSRES, bmpLessres, wxT("Reduce the resolution")); + tool_bar->AddTool(OPJFRAME_VIEWFULLRES, bmpFullres, wxT("Full resolution")); + tool_bar->AddTool(OPJFRAME_VIEWMORERES, bmpMoreres, wxT("Increase the resolution")); + tool_bar->AddSeparator(); + tool_bar->AddTool(OPJFRAME_VIEWPREVCOMP, bmpPrevcomp, wxT("Previous component")); + tool_bar->AddTool(OPJFRAME_VIEWALLCOMPS, bmpAllcomps, wxT("All components")); + tool_bar->AddTool(OPJFRAME_VIEWNEXTCOMP, bmpNextcomp, wxT("Next component")); + tool_bar->Realize(); + + // associate the toolbar with the frame + SetToolBar(tool_bar); + + // show the toolbar? + if (!wxGetApp().m_showtoolbar) + tool_bar->Show(false); + else + tool_bar->Show(true); + + // the logging window + loggingWindow = new wxSashLayoutWindow(this, OPJFRAME_LOGWIN, + wxDefaultPosition, wxSize(400, wxGetApp().m_peekerheight), + wxNO_BORDER | wxSW_3D | wxCLIP_CHILDREN + ); + loggingWindow->SetDefaultSize(wxSize(1000, wxGetApp().m_peekerheight)); + loggingWindow->SetOrientation(wxLAYOUT_HORIZONTAL); + loggingWindow->SetAlignment(wxLAYOUT_BOTTOM); + //loggingWindow->SetBackgroundColour(wxColour(0, 0, 255)); + loggingWindow->SetSashVisible(wxSASH_TOP, true); + + // show the logging? + if (!wxGetApp().m_showpeeker) + loggingWindow->Show(false); + else + loggingWindow->Show(true); + + // create the bottom notebook + m_bookCtrlbottom = new wxNotebook(loggingWindow, BOTTOM_NOTEBOOK_ID, + wxDefaultPosition, wxDefaultSize, + wxBK_LEFT); + + // create the text control of the logger + m_textCtrl = new wxTextCtrl(m_bookCtrlbottom, wxID_ANY, wxT(""), + wxDefaultPosition, wxDefaultSize, + wxTE_MULTILINE | wxSUNKEN_BORDER | wxTE_READONLY + ); + m_textCtrl->SetValue(_T("Logging window\n")); + + // add it to the notebook + m_bookCtrlbottom->AddPage(m_textCtrl, wxT("Log")); + + // 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_RICH + ); + 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"), false); + + // the browser window + markerTreeWindow = new wxSashLayoutWindow(this, OPJFRAME_BROWSEWIN, + wxDefaultPosition, wxSize(wxGetApp().m_browserwidth, 30), + wxNO_BORDER | wxSW_3D | wxCLIP_CHILDREN + ); + markerTreeWindow->SetDefaultSize(wxSize(wxGetApp().m_browserwidth, 1000)); + markerTreeWindow->SetOrientation(wxLAYOUT_VERTICAL); + markerTreeWindow->SetAlignment(wxLAYOUT_LEFT); + //markerTreeWindow->SetBackgroundColour(wxColour(0, 255, 0)); + markerTreeWindow->SetSashVisible(wxSASH_RIGHT, true); + markerTreeWindow->SetExtraBorderSize(0); + + // create the browser notebook + m_bookCtrl = new wxNotebook(markerTreeWindow, LEFT_NOTEBOOK_ID, + wxDefaultPosition, wxDefaultSize, + wxBK_TOP); + + // show the browser? + if (!wxGetApp().m_showbrowser) + markerTreeWindow->Show(false); + else + markerTreeWindow->Show(true); + +#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? + delete wxLog::SetActiveTarget(new wxLogStderr); +#else + // set our text control as the log target + wxLogTextCtrl *logWindow = new wxLogTextCtrl(m_textCtrl); + delete wxLog::SetActiveTarget(logWindow); +#endif + + // associate drop targets with the controls + SetDropTarget(new OPJDnDFile(this)); + +} + +// this is the frame destructor +OPJFrame::~OPJFrame(void) +{ + // save size settings + GetSize(&(wxGetApp().m_framewidth), &(wxGetApp().m_frameheight)); + + // delete all possible things + delete m_bookCtrl; + m_bookCtrl = NULL; + + delete markerTreeWindow; + markerTreeWindow = NULL; + + delete m_textCtrl; + m_textCtrl = NULL; + + delete m_bookCtrlbottom; + m_bookCtrlbottom = NULL; + + delete loggingWindow; + loggingWindow = NULL; +} + +void OPJFrame::OnNotebook(wxNotebookEvent& event) +{ + int sel = event.GetSelection(); + long childnum; + + m_bookCtrl->GetPageText(sel).ToLong(&childnum); + + if (m_childhash[childnum]) + m_childhash[childnum]->Activate(); + + //wxLogMessage(wxT("Selection changed (now %d --> %d)"), childnum, m_childhash[childnum]->m_winnumber); + +} + + +void OPJFrame::Resize(int number) +{ + wxSize size = GetClientSize(); +} + +void OPJFrame::OnSetsEnco(wxCommandEvent& event) +{ + int n; + + OPJEncoderDialog dialog(this, event.GetId()); + + if (dialog.ShowModal() == wxID_OK) { + + // load settings + wxGetApp().m_subsampling = dialog.m_subsamplingCtrl->GetValue(); + wxGetApp().m_origin = dialog.m_originCtrl->GetValue(); + wxGetApp().m_rates = dialog.m_rateCtrl->GetValue(); + wxGetApp().m_quality = dialog.m_qualityCtrl->GetValue(); + wxGetApp().m_enablequality = dialog.m_qualityRadio->GetValue(); + wxGetApp().m_multicomp = dialog.m_mctCheck->GetValue(); + wxGetApp().m_irreversible = dialog.m_irrevCheck->GetValue(); + wxGetApp().m_resolutions = dialog.m_resolutionsCtrl->GetValue(); + wxGetApp().m_cbsize = dialog.m_cbsizeCtrl->GetValue(); + wxGetApp().m_prsize = dialog.m_prsizeCtrl->GetValue(); + wxGetApp().m_tsize = dialog.m_tsizeCtrl->GetValue(); + wxGetApp().m_torigin = dialog.m_toriginCtrl->GetValue(); + wxGetApp().m_progression = dialog.progressionBox->GetSelection(); + wxGetApp().m_enablesop = dialog.m_sopCheck->GetValue(); + wxGetApp().m_enableeph = dialog.m_ephCheck->GetValue(); + wxGetApp().m_enablebypass = dialog.m_enablebypassCheck->GetValue(); + wxGetApp().m_enablereset = dialog.m_enableresetCheck->GetValue(); + wxGetApp().m_enablerestart = dialog.m_enablerestartCheck->GetValue(); + wxGetApp().m_enablevsc = dialog.m_enablevscCheck->GetValue(); + wxGetApp().m_enableerterm = dialog.m_enableertermCheck->GetValue(); + wxGetApp().m_enablesegmark = dialog.m_enablesegmarkCheck->GetValue(); + wxGetApp().m_enableidx = dialog.m_enableidxCheck->GetValue(); + wxGetApp().m_index = dialog.m_indexCtrl->GetValue(); + wxGetApp().m_enablecomm = dialog.m_enablecommCheck->GetValue(); + wxGetApp().m_comment = dialog.m_commentCtrl->GetValue(); + wxGetApp().m_enablepoc = dialog.m_enablepocCheck->GetValue(); + wxGetApp().m_poc = dialog.m_pocCtrl->GetValue(); +#ifdef USE_JPWL + wxGetApp().m_enablejpwle = dialog.m_enablejpwlCheck->GetValue(); + for (n = 0; n < MYJPWL_MAX_NO_TILESPECS; n++) { + wxGetApp().m_hprotsel[n] = dialog.m_hprotChoice[n]->GetSelection(); + wxGetApp().m_htileval[n] = dialog.m_htileCtrl[n]->GetValue(); + wxGetApp().m_pprotsel[n] = dialog.m_pprotChoice[n]->GetSelection(); + wxGetApp().m_ptileval[n] = dialog.m_ptileCtrl[n]->GetValue(); + wxGetApp().m_ppackval[n] = dialog.m_ppackCtrl[n]->GetValue(); + wxGetApp().m_sensisel[n] = dialog.m_sensiChoice[n]->GetSelection(); + wxGetApp().m_stileval[n] = dialog.m_stileCtrl[n]->GetValue(); + } +#endif // USE_JPWL + }; +} + +void OPJFrame::OnSetsDeco(wxCommandEvent& event) +{ + OPJDecoderDialog dialog(this, event.GetId()); + + if (dialog.ShowModal() == wxID_OK) { + + // load settings + wxGetApp().m_enabledeco = dialog.m_enabledecoCheck->GetValue(); + wxGetApp().m_enableparse = dialog.m_enableparseCheck->GetValue(); + wxGetApp().m_resizemethod = dialog.m_resizeBox->GetSelection() - 1; + wxGetApp().m_reducefactor = dialog.m_reduceCtrl->GetValue(); + wxGetApp().m_qualitylayers = dialog.m_layerCtrl->GetValue(); + wxGetApp().m_components = dialog.m_numcompsCtrl->GetValue(); + wxGetApp().m_framenum = dialog.m_framenumCtrl->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& event) +{ + OPJChildFrame *currchild; + wxString eventstring = event.GetString(); + + //wxLogMessage(wxT("OnFit:%d:%s"), event.GetInt(), eventstring); + + // current child + if (event.GetInt() >= 1) { + currchild = m_childhash[event.GetInt()]; + } else { + currchild = (OPJChildFrame *) GetActiveChild(); + } + + // problems + 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(-1, 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(); + + // resizing enabled? + if (wxGetApp().m_resizemethod == -1) { + + zooml = 100; + + } else { + + if (zooml < 0) { + // find a fit-to-width zoom + int wzooml, hzooml; + //wxSize clientsize = currframe->m_canvas->GetClientSize(); + wxSize clientsize = currframe->m_frame->GetActiveChild()->GetClientSize(); + wzooml = (int) floor(100.0 * (double) clientsize.GetWidth() / (double) (2 * OPJ_CANVAS_BORDER + currframe->m_canvas->m_image100.GetWidth())); + hzooml = (int) floor(100.0 * (double) clientsize.GetHeight() / (double) (2 * OPJ_CANVAS_BORDER + currframe->m_canvas->m_image100.GetHeight())); + zooml = wxMin(100, wxMin(wzooml, hzooml)); + } + } + + if (zooml != 100) + new_image.Rescale((int) ((double) zooml * (double) new_image.GetWidth() / 100.0), + (int) ((double) zooml * (double) new_image.GetHeight() / 100.0), + wxGetApp().m_resizemethod ? wxIMAGE_QUALITY_HIGH : 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(); + + wxLogMessage(wxT("Rescale said %d%%"), zooml); + + // update zoom + currframe->m_canvas->m_zooml = zooml; +} + + +void OPJFrame::OnReload(wxCommandEvent& event) +{ + OPJChildFrame *currframe = (OPJChildFrame *) GetActiveChild(); + + if (currframe) { + OPJDecoThread *dthread = currframe->m_canvas->CreateDecoThread(); + + if (dthread->Run() != wxTHREAD_NO_ERROR) + wxLogMessage(wxT("Can't start deco thread!")); + else + wxLogMessage(wxT("New deco thread started.")); + + currframe->m_canvas->Refresh(); + + // update zoom + //currframe->m_canvas->m_zooml = zooml; + } +} + +void OPJFrame::OnPrevFrame(wxCommandEvent& event) +{ + if (--wxGetApp().m_framenum < 0) + wxGetApp().m_framenum = 0; + + wxCommandEvent e; + OnReload(e); +} + +void OPJFrame::OnHomeFrame(wxCommandEvent& event) +{ + wxGetApp().m_framenum = 0; + + wxCommandEvent e; + OnReload(e); +} + +void OPJFrame::OnNextFrame(wxCommandEvent& event) +{ + ++wxGetApp().m_framenum; + + wxCommandEvent e; + OnReload(e); +} + +void OPJFrame::OnLessLayers(wxCommandEvent& event) +{ + if (--wxGetApp().m_qualitylayers < 1) + wxGetApp().m_qualitylayers = 1; + + wxCommandEvent e; + OnReload(e); +} + +void OPJFrame::OnAllLayers(wxCommandEvent& event) +{ + wxGetApp().m_qualitylayers = 0; + + wxCommandEvent e; + OnReload(e); +} + +void OPJFrame::OnMoreLayers(wxCommandEvent& event) +{ + ++wxGetApp().m_qualitylayers; + + wxCommandEvent e; + OnReload(e); +} + +void OPJFrame::OnLessRes(wxCommandEvent& event) +{ + ++wxGetApp().m_reducefactor; + + wxCommandEvent e; + OnReload(e); +} + +void OPJFrame::OnFullRes(wxCommandEvent& event) +{ + wxGetApp().m_reducefactor = 0; + + wxCommandEvent e; + OnReload(e); +} + +void OPJFrame::OnMoreRes(wxCommandEvent& event) +{ + if (--wxGetApp().m_reducefactor < 0) + wxGetApp().m_reducefactor = 0; + + wxCommandEvent e; + OnReload(e); +} + +void OPJFrame::OnPrevComp(wxCommandEvent& event) +{ + if (--wxGetApp().m_components < 1) + wxGetApp().m_components = 1; + + wxCommandEvent e; + OnReload(e); +} + +void OPJFrame::OnAllComps(wxCommandEvent& event) +{ + wxGetApp().m_components = 0; + + wxCommandEvent e; + OnReload(e); +} + +void OPJFrame::OnNextComp(wxCommandEvent& event) +{ + ++wxGetApp().m_components; + + wxCommandEvent e; + OnReload(e); +} + +void OPJFrame::OnToggleBrowser(wxCommandEvent& WXUNUSED(event)) +{ + if (markerTreeWindow->IsShown()) + markerTreeWindow->Show(false); + else + markerTreeWindow->Show(true); + + wxLayoutAlgorithm layout; + layout.LayoutMDIFrame(this); + + wxGetApp().m_showbrowser = markerTreeWindow->IsShown(); + + // Leaves bits of itself behind sometimes + GetClientWindow()->Refresh(); +} + +void OPJFrame::OnTogglePeeker(wxCommandEvent& WXUNUSED(event)) +{ + if (loggingWindow->IsShown()) + loggingWindow->Show(false); + else + loggingWindow->Show(true); + + wxLayoutAlgorithm layout; + layout.LayoutMDIFrame(this); + + wxGetApp().m_showpeeker = loggingWindow->IsShown(); + + // Leaves bits of itself behind sometimes + GetClientWindow()->Refresh(); +} + +void OPJFrame::OnToggleToolbar(wxCommandEvent& WXUNUSED(event)) +{ + if (tool_bar->IsShown()) + tool_bar->Show(false); + else + tool_bar->Show(true); + + wxLayoutAlgorithm layout; + layout.LayoutMDIFrame(this); + + wxGetApp().m_showtoolbar = tool_bar->IsShown(); + + // Leaves bits of itself behind sometimes + GetClientWindow()->Refresh(); +} + +void OPJFrame::OnSashDrag(wxSashEvent& event) +{ + int wid, hei; + + if (event.GetDragStatus() == wxSASH_STATUS_OUT_OF_RANGE) + return; + + 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; + } + } + + wxLayoutAlgorithm layout; + layout.LayoutMDIFrame(this); + + // Leaves bits of itself behind sometimes + GetClientWindow()->Refresh(); + + // update dimensions + markerTreeWindow->GetSize(&wid, &hei); + wxGetApp().m_browserwidth = wid; + + loggingWindow->GetSize(&wid, &hei); + wxGetApp().m_peekerheight = hei; + +} + +void OPJFrame::OnThreadLogmsg(wxCommandEvent& event) +{ +#if 1 + wxLogMessage(wxT("Frame got message from worker thread: %d"), event.GetInt()); + wxLogMessage(event.GetString()); +#else + int n = event.GetInt(); + if ( n == -1 ) + { + m_dlgProgress->Destroy(); + m_dlgProgress = (wxProgressDialog *)NULL; + + // the dialog is aborted because the event came from another thread, so + // we may need to wake up the main event loop for the dialog to be + // really closed + wxWakeUpIdle(); + } + else + { + if ( !m_dlgProgress->Update(n) ) + { + wxCriticalSectionLocker lock(m_critsectWork); + + m_cancelled = true; + } + } +#endif +} + + +// physically save the file +void OPJFrame::SaveFile(wxArrayString paths, wxArrayString filenames) +{ + size_t count = paths.GetCount(); + wxString msg, s; + + if (wxFile::Exists(paths[0].c_str())) { + + s.Printf(wxT("File %s already exists. Do you want to overwrite it?\n"), filenames[0].c_str()); + wxMessageDialog dialog3(this, s, _T("File exists"), wxYES_NO); + if (dialog3.ShowModal() == wxID_NO) + return; + } + + /*s.Printf(_T("File %d: %s (%s)\n"), (int)0, paths[0].c_str(), filenames[0].c_str()); + msg += s; + + wxMessageDialog dialog2(this, msg, _T("Selected files")); + dialog2.ShowModal();*/ + + if (!GetActiveChild()) + return; + + ((OPJChildFrame *) GetActiveChild())->m_canvas->m_savename = paths[0]; + + OPJEncoThread *ethread = ((OPJChildFrame *) GetActiveChild())->m_canvas->CreateEncoThread(); + + if (ethread->Run() != wxTHREAD_NO_ERROR) + wxLogMessage(wxT("Can't start enco thread!")); + else + wxLogMessage(wxT("New enco thread started.")); + + +} + +// physically open the files +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()); + + msg += s; + + /*wxMessageDialog dialog2(this, msg, _T("Selected files")); + dialog2.ShowModal();*/ + + // 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; + + // create own marker tree + m_treehash[winNumber] = new OPJMarkerTree(m_bookCtrl, subframe, 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); + + for (unsigned 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)) +{ + wxString wildcards = +#ifdef __WXMOTIF__ + wxT("JPEG 2000 files (*.jp2,*.j2k,*.j2c,*.mj2)|*.*j*2*"); +#else +#if wxUSE_LIBOPENJPEG + wxT("JPEG 2000 files (*.jp2,*.j2k,*.j2c,*.mj2)|*.jp2;*.j2k;*.j2c;*.mj2") +#endif +#if USE_MXF + wxT("|MXF JPEG 2000 video (*.mxf)|*.mxf") +#endif // USE_MXF +#if wxUSE_LIBJPEG + wxT("|JPEG files (*.jpg)|*.jpg") +#endif +#if OPJ_MANYFORMATS + wxT("|BMP files (*.bmp)|*.bmp") + wxT("|PNG files (*.png)|*.png") + wxT("|GIF files (*.gif)|*.gif") + wxT("|PNM files (*.pnm)|*.pnm") + wxT("|TIFF files (*.tif,*.tiff)|*.tif*") +#endif + wxT("|All files|*"); +#endif + wxFileDialog dialog(this, _T("Open image file(s)"), + wxEmptyString, wxEmptyString, wildcards, + wxFD_OPEN|wxFD_MULTIPLE); + + if (dialog.ShowModal() == wxID_OK) { + wxArrayString paths, filenames; + + dialog.GetPaths(paths); + dialog.GetFilenames(filenames); + + OpenFiles(paths, filenames); + } + +} + +void OPJFrame::OnFileSaveAs(wxCommandEvent& WXUNUSED(event)) +{ + wxString wildcards = +#ifdef wxUSE_LIBOPENJPEG +#ifdef __WXMOTIF__ + wxT("JPEG 2000 codestream (*.j2k)|*.*j*2*"); +#else + wxT("JPEG 2000 codestream (*.j2k)|*.j2k") + wxT("|JPEG 2000 file format (*.jp2)|*.jp2"); +#endif +#else + wxT("Houston we have a problem"); +#endif + + wxFileDialog dialog(this, _T("Save image file"), + wxEmptyString, wxEmptyString, wildcards, + wxFD_SAVE); + + if (dialog.ShowModal() == wxID_OK) { + wxArrayString paths, filenames; + + dialog.GetPaths(paths); + dialog.GetFilenames(filenames); + + SaveFile(paths, filenames); + } + + +} + +void OPJFrame::OnMemoryOpen(wxCommandEvent& WXUNUSED(event)) +{ + // do nothing + return; + + wxTextEntryDialog dialog(this, wxT("Memory HEX address range: start_address-stop_address"), + wxT("Decode a memory buffer"), + wxT("0x-0x"), + wxOK | wxCANCEL | wxCENTRE, + wxDefaultPosition); + + if (dialog.ShowModal() == wxID_OK) { + + } + +} + +BEGIN_EVENT_TABLE(OPJCanvas, wxScrolledWindow) + EVT_MOUSE_EVENTS(OPJCanvas::OnEvent) + EVT_MENU(OPJCANVAS_THREADSIGNAL, OPJCanvas::OnThreadSignal) +END_EVENT_TABLE() + +// Define a constructor for my canvas +OPJCanvas::OPJCanvas(wxFileName fname, wxWindow *parent, const wxPoint& pos, const wxSize& size) + : wxScrolledWindow(parent, wxID_ANY, pos, size, + wxSUNKEN_BORDER | wxNO_FULL_REPAINT_ON_RESIZE) +{ + SetBackgroundColour(OPJ_CANVAS_COLOUR); + + m_fname = fname; + m_childframe = (OPJChildFrame *) parent; + // 100% zoom + m_zooml = 100; + + + OPJDecoThread *dthread = CreateDecoThread(); + + if (dthread->Run() != wxTHREAD_NO_ERROR) + wxLogMessage(wxT("Can't start deco thread!")); + else + wxLogMessage(wxT("New deco thread started.")); + + // 100% zoom + //m_zooml = 100; + +} + +OPJDecoThread *OPJCanvas::CreateDecoThread(void) +{ + OPJDecoThread *dthread = new OPJDecoThread(this); + + if (dthread->Create() != wxTHREAD_NO_ERROR) + wxLogError(wxT("Can't create deco thread!")); + + wxCriticalSectionLocker enter(wxGetApp().m_deco_critsect); + wxGetApp().m_deco_threads.Add(dthread); + + return dthread; +} + +OPJEncoThread *OPJCanvas::CreateEncoThread(void) +{ + OPJEncoThread *ethread = new OPJEncoThread(this); + + if (ethread->Create() != wxTHREAD_NO_ERROR) + wxLogError(wxT("Can't create enco thread!")); + + wxCriticalSectionLocker enter(wxGetApp().m_enco_critsect); + wxGetApp().m_enco_threads.Add(ethread); + + return ethread; +} + +#define activeoverlay 0 +// Define the repainting behaviour +void OPJCanvas::OnDraw(wxDC& dc) +{ + if (m_image.Ok()) { + dc.DrawBitmap(m_image, OPJ_CANVAS_BORDER, OPJ_CANVAS_BORDER); + + if (activeoverlay) { + dc.SetPen(*wxRED_PEN); + dc.SetBrush(*wxTRANSPARENT_BRUSH); + //int tw, th; + dc.DrawRectangle(OPJ_CANVAS_BORDER, OPJ_CANVAS_BORDER, + (unsigned long int) (0.5 + (double) m_zooml * (double) m_childframe->m_twidth / 100.0), + (unsigned long int) (0.5 + (double) m_zooml * (double) m_childframe->m_theight / 100.0)); + } + + } else { + dc.SetFont(*wxSWISS_FONT); + dc.SetPen(*wxBLACK_PEN); +#ifdef __WXGTK__ + dc.DrawText(_T("Decoding image, please wait... (press \"Zoom to Fit\" to show the image)"), 40, 50); +#else + dc.DrawText(_T("Decoding image, please wait..."), 40, 50); +#endif + } +} + +// This implements a tiny doodling program! Drag the mouse using +// the left button. +void OPJCanvas::OnEvent(wxMouseEvent& event) +{ +#if USE_PENCIL_ON_CANVAS + wxClientDC dc(this); + PrepareDC(dc); + + wxPoint pt(event.GetLogicalPosition(dc)); + + if ((xpos > -1) && (ypos > -1) && event.Dragging()) { + dc.SetPen(*wxRED_PEN); + dc.DrawLine(xpos, ypos, pt.x, pt.y); + } + xpos = pt.x; + ypos = pt.y; +#endif +} + +void OPJFrame::OnSize(wxSizeEvent& WXUNUSED(event)) +{ + wxLayoutAlgorithm layout; + layout.LayoutMDIFrame(this); +} + +void OPJCanvas::OnThreadSignal(wxCommandEvent& event) +{ +#if 1 + wxLogMessage(wxT("Canvas got signal from deco thread: %d"), event.GetInt()); + wxLogMessage(event.GetString()); +#else + int n = event.GetInt(); + if ( n == -1 ) + { + m_dlgProgress->Destroy(); + m_dlgProgress = (wxProgressDialog *)NULL; + + // the dialog is aborted because the event came from another thread, so + // we may need to wake up the main event loop for the dialog to be + // really closed + wxWakeUpIdle(); + } + else + { + if ( !m_dlgProgress->Update(n) ) + { + wxCriticalSectionLocker lock(m_critsectWork); + + m_cancelled = true; + } + } +#endif +} + + +// Note that OPJFRAME_FILEOPEN and OPJFRAME_HELPABOUT commands get passed +// to the parent window for processing, so no need to +// duplicate event handlers here. + +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) +END_EVENT_TABLE() + +OPJChildFrame::OPJChildFrame(OPJFrame *parent, wxFileName fname, int winnumber, const wxString& title, const wxPoint& pos, const wxSize& size, +const long style): + wxMDIChildFrame(parent, wxID_ANY, title, pos, size, style) +{ + m_frame = (OPJFrame *) parent; + m_canvas = NULL; + //my_children.Append(this); + m_fname = fname; + m_winnumber = winnumber; + SetTitle(wxString::Format(_T("%d: "), m_winnumber) + m_fname.GetFullName()); + + // Give it an icon (this is ignored in MDI mode: uses resources) +#ifdef __WXMSW__ + SetIcon(wxIcon(wxT("OPJChild16"))); +#endif + + // Give it a status line + /*CreateStatusBar();*/ + + int width, height; + GetClientSize(&width, &height); + + OPJCanvas *canvas = new OPJCanvas(fname, this, wxPoint(0, 0), wxSize(width, height)); +#if USE_PENCIL_ON_CANVAS + canvas->SetCursor(wxCursor(wxCURSOR_PENCIL)); +#endif + m_canvas = canvas; + + // Give it scrollbars + canvas->SetScrollbars(20, 20, 5, 5); + + Show(true); + Maximize(true); + + /*wxLogError(wxString::Format(wxT("Created tree %d (0x%x)"), m_winnumber, m_frame->m_treehash[m_winnumber]));*/ + +} + +OPJChildFrame::~OPJChildFrame(void) +{ + //my_children.DeleteObject(this); +} + + +void OPJChildFrame::OnClose(wxCloseEvent& event) +{ + for (unsigned 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; + } + } + Destroy(); + + wxLogMessage(wxT("Closed: %d"), m_winnumber); +} + +void OPJChildFrame::OnActivate(wxActivateEvent& event) +{ + /*if (event.GetActive() && m_canvas) + m_canvas->SetFocus();*/ +} + +void OPJChildFrame::OnGotFocus(wxFocusEvent& event) +{ + // we need to check if the notebook is being destroyed or not + if (!m_frame->m_bookCtrl) + return; + + for (unsigned 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->ChangeSelection(p); + break; + } + + } + + //wxLogMessage(wxT("Got focus: %d (%x)"), m_winnumber, event.GetWindow()); +} + +void OPJChildFrame::OnLostFocus(wxFocusEvent& event) +{ + //wxLogMessage(wxT("Lost focus: %d (%x)"), m_winnumber, event.GetWindow()); +} + + +//////////////////////////////// +// drag and drop +//////////////////////////////// + +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; +} + diff --git a/applications/OPJViewer/source/OPJViewer.h b/applications/OPJViewer/source/OPJViewer.h index e0e615bf..a484e2ea 100644 --- a/applications/OPJViewer/source/OPJViewer.h +++ b/applications/OPJViewer/source/OPJViewer.h @@ -1,812 +1,812 @@ -/* - * Copyright (c) 2007, Digital Signal Processing Laboratory, Università degli studi di Perugia (UPG), Italy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are 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. - */ -///////////////////////////////////////////////////////////////////////////// -// Name: sashtest.h -// Purpose: Layout window/sash sample -// Author: Julian Smart -// Modified by: -// Created: 04/01/98 -// RCS-ID: $Id: sashtest.h,v 1.5 2005/06/02 12:04:24 JS Exp $ -// Copyright: (c) Julian Smart -// Licence: wxWindows license -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// -// Name: treectrl.h -// Purpose: wxTreeCtrl sample -// Author: Julian Smart -// Modified by: -// Created: 04/01/98 -// RCS-ID: $Id: treetest.h,v 1.50 2006/11/04 11:26:51 VZ Exp $ -// 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__ - -// For compilers that support precompilation, includes "wx/wx.h". -#include "wx/wxprec.h" - -#ifdef __BORLANDC__ -#pragma hdrstop -#endif - -#ifndef WX_PRECOMP -#include "wx/wx.h" -#include "wx/mdi.h" -#endif - -#include "wx/toolbar.h" -#include "wx/laywin.h" -#include "wx/treectrl.h" - -#include "icon1.xpm" -#include "icon2.xpm" -#include "icon3.xpm" -#include "icon4.xpm" -#include "icon5.xpm" - -#include "wx/filedlg.h" -#include "wx/toolbar.h" -#include -#include -#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 - -#include - -#include "wx/toolbar.h" -#include "wx/artprov.h" - -#include "libopenjpeg/openjpeg.h" - -//#include "imagj2k.h" -//#include "imagjp2.h" -//#include "imagmj2.h" -#include "imagjpeg2000.h" -#ifdef USE_MXF -#include "imagmxf.h" -#endif // USE_MXF - -#ifdef __WXMSW__ -typedef unsigned __int64 int8byte; -#endif // __WXMSW__ - -#ifdef __WXGTK__ -typedef unsigned long long int8byte; -#endif // __WXGTK__ - -#define USE_GENERIC_TREECTRL 0 -#define USE_PENCIL_ON_CANVAS 0 - -#if USE_GENERIC_TREECTRL -#include "wx/generic/treectlg.h" -#ifndef wxTreeCtrl -#define wxTreeCtrl wxGenericTreeCtrl -#define sm_classwxTreeCtrl sm_classwxGenericTreeCtrl -#endif -#endif - -#define OPJ_APPLICATION wxT("OPJViewer") -#define OPJ_APPLICATION_NAME wxT("OpenJPEG Viewer") -#define OPJ_APPLICATION_VERSION wxT("0.4 beta") -#define OPJ_APPLICATION_TITLEBAR OPJ_APPLICATION_NAME wxT(" ") OPJ_APPLICATION_VERSION -#define OPJ_APPLICATION_COPYRIGHT wxT("(C) 2007-2008, Giuseppe Baruffa") -#define OPJ_APPLICATION_VENDOR wxT("OpenJPEG") - -#ifdef __WXMSW__ -#define OPJ_APPLICATION_PLATFORM wxT("Windows") -#endif - -#ifdef __WXGTK__ -#define OPJ_APPLICATION_PLATFORM wxT("Linux") -#endif - -#define OPJ_FRAME_WIDTH 800 -#define OPJ_FRAME_HEIGHT 600 - -#define OPJ_BROWSER_WIDTH 300 -#define OPJ_PEEKER_HEIGHT 130 - -#define OPJ_CANVAS_BORDER 10 -#define OPJ_CANVAS_COLOUR *wxWHITE - - - -#ifdef USE_JPWL - -//#define MYJPWL_MAX_NO_TILESPECS JPWL_MAX_NO_TILESPECS -#define MYJPWL_MAX_NO_TILESPECS 4 - -#endif // USE_JPWL - - -class OPJDecoThread; -class OPJEncoThread; -class OPJParseThread; -WX_DEFINE_ARRAY_PTR(wxThread *, wxArrayThread); -class OPJChildFrame; - -////////////////////////////////// -// this is our main application // -////////////////////////////////// -class OPJViewerApp: public wxApp -{ - // public methods and variables - public: - - // class constructor - OPJViewerApp() { m_showImages = true; m_showButtons = false; } - - // other methods - bool OnInit(void); - int OnExit(void); - void SetShowImages(bool show) { m_showImages = show; } - bool ShowImages() const { return m_showImages; } - void ShowCmdLine(const wxCmdLineParser& parser); - - // all the threads currently alive - as soon as the thread terminates, it's - // removed from the array - wxArrayThread m_deco_threads, m_parse_threads, m_enco_threads; - - // crit section protects access to all of the arrays below - wxCriticalSection m_deco_critsect, m_parse_critsect, m_enco_critsect; - - // semaphore used to wait for the threads to exit, see OPJFrame::OnQuit() - wxSemaphore m_deco_semAllDone, m_parse_semAllDone, m_enco_semAllDone; - - // the last exiting thread should post to m_semAllDone if this is true - // (protected by the same m_critsect) - bool m_deco_waitingUntilAllDone, m_parse_waitingUntilAllDone, m_enco_waitingUntilAllDone; - - // the list of all filenames written in the command line - wxArrayString m_filelist; - - // displaying engine parameters - int m_resizemethod; - - // decoding engine parameters - bool m_enabledeco, m_enableparse; - int m_reducefactor, m_qualitylayers, m_components, m_framenum; -#ifdef USE_JPWL - bool m_enablejpwl, m_enablejpwle; - int m_expcomps, m_maxtiles; -#endif // USE_JPWL - int m_framewidth, m_frameheight; - - // encoding engine parameters - wxString m_subsampling, m_origin, m_rates, m_comment, m_index, m_quality; - wxString m_cbsize, m_prsize, m_tsize, m_torigin, m_poc; - bool m_enablecomm, m_enableidx, m_multicomp, m_irreversible, m_enablesop, m_enableeph; - bool m_enablebypass, m_enablereset, m_enablerestart, m_enablevsc, m_enableerterm; - bool m_enablesegmark, m_enablepoc; - bool m_enablequality; - int m_resolutions, m_progression; -#ifdef USE_JPWL - int m_hprotsel[MYJPWL_MAX_NO_TILESPECS], m_pprotsel[MYJPWL_MAX_NO_TILESPECS]; - int m_htileval[MYJPWL_MAX_NO_TILESPECS], m_ptileval[MYJPWL_MAX_NO_TILESPECS], - m_ppackval[MYJPWL_MAX_NO_TILESPECS]; - int m_sensisel[MYJPWL_MAX_NO_TILESPECS], m_stileval[MYJPWL_MAX_NO_TILESPECS]; -#endif // USE_JPWL - - // some layout settings - bool m_showtoolbar, m_showbrowser, m_showpeeker; - int m_browserwidth, m_peekerheight; - - // application configuration - wxConfig *OPJconfig; - - // private methods and variables - private: - bool m_showImages, m_showButtons; - -}; - -DECLARE_APP(OPJViewerApp) - -/////////////////////////////////////////// -// this canvas is used to draw the image // -/////////////////////////////////////////// -class OPJCanvas: public wxScrolledWindow -{ - // public methods and variables - public: - - // class constructor - OPJCanvas(wxFileName fname, wxWindow *parent, const wxPoint& pos, const wxSize& size); - - virtual void OnDraw(wxDC& dc); - void OnEvent(wxMouseEvent& event); - void WriteText(const wxString& text) { -#ifndef __WXGTK__ - wxMutexGuiEnter(); -#endif //__WXGTK__ - wxLogMessage(text); -#ifndef __WXGTK__ - wxMutexGuiLeave(); -#endif //__WXGTK__ - } - - void OnThreadSignal(wxCommandEvent& event); - - OPJDecoThread *CreateDecoThread(void); - OPJEncoThread *CreateEncoThread(void); - - - OPJChildFrame *m_childframe; - - wxBitmap m_image, m_image100; - wxFileName m_fname, m_savename; - long m_zooml; - - DECLARE_EVENT_TABLE() -}; - -/////////////////////////////////////////////////// -// the data associated to each tree leaf or node // -/////////////////////////////////////////////////// -class OPJMarkerData : public wxTreeItemData -{ - // public methods and variables - public: - - // class constructor - 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; } - - void ShowInfo(wxTreeCtrl *tree); - const wxChar *GetDesc1() const { return m_desc.c_str(); } - const wxChar *GetDesc2() const { return m_filestring.c_str(); } - wxFileOffset m_start, m_length; - wxString m_desc; - - // private methods and variables - private: - wxString m_filestring; -}; - - -class OPJMarkerTree : public wxTreeCtrl -{ -public: - enum - { - TreeCtrlIcon_File, - TreeCtrlIcon_FileSelected, - TreeCtrlIcon_Folder, - TreeCtrlIcon_FolderSelected, - TreeCtrlIcon_FolderOpened - }; - - OPJMarkerTree() { }; - OPJMarkerTree(wxWindow *parent, OPJChildFrame *subframe, wxFileName fname, wxString name, const wxWindowID id, - const wxPoint& pos, const wxSize& size, - long style); - virtual ~OPJMarkerTree(){}; - OPJParseThread *CreateParseThread(wxTreeItemId parentid = 0x00, OPJChildFrame *subframe = NULL); - void WriteText(const wxString& text) { wxMutexGuiEnter(); wxLogMessage(text); wxMutexGuiLeave(); } - - wxFileName m_fname; - wxTextCtrl *m_peektextCtrl; - OPJChildFrame *m_childframe; - - /*void OnBeginDrag(wxTreeEvent& event); - void OnBeginRDrag(wxTreeEvent& event); - void OnEndDrag(wxTreeEvent& event);*/ - /*void OnBeginLabelEdit(wxTreeEvent& event); - void OnEndLabelEdit(wxTreeEvent& event);*/ - /*void OnDeleteItem(wxTreeEvent& event);*/ - /*void OnContextMenu(wxContextMenuEvent& event);*/ - void OnItemMenu(wxTreeEvent& event); - /*void OnGetInfo(wxTreeEvent& event); - void OnSetInfo(wxTreeEvent& event);*/ - /*void OnItemExpanded(wxTreeEvent& event);*/ - void OnItemExpanding(wxTreeEvent& event); - /*void OnItemCollapsed(wxTreeEvent& event); - void OnItemCollapsing(wxTreeEvent& event);*/ - void OnSelChanged(wxTreeEvent& event); - /*void OnSelChanging(wxTreeEvent& event);*/ - /*void OnTreeKeyDown(wxTreeEvent& event);*/ - /*void OnItemActivated(wxTreeEvent& event);*/ - /*void OnItemRClick(wxTreeEvent& event);*/ - /*void OnRMouseDown(wxMouseEvent& event); - void OnRMouseUp(wxMouseEvent& event); - void OnRMouseDClick(wxMouseEvent& event);*/ - /*void GetItemsRecursively(const wxTreeItemId& idParent, - wxTreeItemIdValue cookie = 0);*/ - - void CreateImageList(int size = 16); - void CreateButtonsImageList(int size = 11); - - /*void AddTestItemsToTree(size_t numChildren, size_t depth);*/ - /*void DoSortChildren(const wxTreeItemId& item, bool reverse = false) - { m_reverseSort = reverse; wxTreeCtrl::SortChildren(item); }*/ - /*void DoEnsureVisible() { if (m_lastItem.IsOk()) EnsureVisible(m_lastItem); }*/ - /*void DoToggleIcon(const wxTreeItemId& item);*/ - /*void ShowMenu(wxTreeItemId id, const wxPoint& pt);*/ - - int ImageSize(void) const { return m_imageSize; } - - void SetLastItem(wxTreeItemId id) { m_lastItem = id; } - -protected: - /*virtual int OnCompareItems(const wxTreeItemId& i1, const wxTreeItemId& i2);*/ - - // is this the test item which we use in several event handlers? - /*bool IsTestItem(const wxTreeItemId& item) - { - // the test item is the first child folder - return GetItemParent(item) == GetRootItem() && !GetPrevSibling(item); - }*/ - -private: - /*void AddItemsRecursively(const wxTreeItemId& idParent, - size_t nChildren, - size_t depth, - size_t folder);*/ - - void LogEvent(const wxChar *name, const wxTreeEvent& event); - - int m_imageSize; // current size of images - bool m_reverseSort; // flag for OnCompareItems - wxTreeItemId m_lastItem, // for OnEnsureVisible() - m_draggedItem; // item being dragged right now - - // NB: due to an ugly wxMSW hack you _must_ use DECLARE_DYNAMIC_CLASS() - // if you want your overloaded OnCompareItems() to be called. - // OTOH, if you don't want it you may omit the next line - this will - // make default (alphabetical) sorting much faster under wxMSW. - DECLARE_DYNAMIC_CLASS(OPJMarkerTree) - DECLARE_EVENT_TABLE() -}; - -// this hash map stores all the trees of currently opened images, with an integer key -WX_DECLARE_HASH_MAP(int, OPJMarkerTree*, wxIntegerHash, wxIntegerEqual, OPJMarkerTreeHash); - -// this hash map stores all the children of currently opened images, with an integer key -WX_DECLARE_HASH_MAP(int, OPJChildFrame*, wxIntegerHash, wxIntegerEqual, OPJChildFrameHash); - -// Define a new frame -class OPJFrame: public wxMDIParentFrame -{ - public: - - OPJFrame(wxWindow *parent, const wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, const long style); - - ~OPJFrame(void); - void OnSize(wxSizeEvent& WXUNUSED(event)); - void OnAbout(wxCommandEvent& WXUNUSED(event)); - void OnFileOpen(wxCommandEvent& WXUNUSED(event)); - void OnFileSaveAs(wxCommandEvent& WXUNUSED(event)); - void OnMemoryOpen(wxCommandEvent& WXUNUSED(event)); - void OnQuit(wxCommandEvent& WXUNUSED(event)); - void OnClose(wxCommandEvent& WXUNUSED(event)); - void OnZoom(wxCommandEvent& WXUNUSED(event)); - void OnFit(wxCommandEvent& event); - void OnToggleBrowser(wxCommandEvent& WXUNUSED(event)); - void OnTogglePeeker(wxCommandEvent& WXUNUSED(event)); - void OnToggleToolbar(wxCommandEvent& WXUNUSED(event)); - void OnReload(wxCommandEvent& event); - void OnPrevFrame(wxCommandEvent& event); - void OnHomeFrame(wxCommandEvent& event); - void OnNextFrame(wxCommandEvent& event); - void OnLessLayers(wxCommandEvent& event); - void OnAllLayers(wxCommandEvent& event); - void OnMoreLayers(wxCommandEvent& event); - void OnLessRes(wxCommandEvent& event); - void OnFullRes(wxCommandEvent& event); - void OnMoreRes(wxCommandEvent& event); - void OnPrevComp(wxCommandEvent& event); - void OnAllComps(wxCommandEvent& event); - void OnNextComp(wxCommandEvent& event); - void OnSetsEnco(wxCommandEvent& event); - void OnSetsDeco(wxCommandEvent& event); - void OnSashDrag(wxSashEvent& event); - void OpenFiles(wxArrayString paths, wxArrayString filenames); - void SaveFile(wxArrayString paths, wxArrayString filenames); - void OnNotebook(wxNotebookEvent& event); - void Rescale(int scale, OPJChildFrame *child); - void OnThreadLogmsg(wxCommandEvent& event); - - OPJMarkerTreeHash m_treehash; - OPJChildFrameHash m_childhash; - wxSashLayoutWindow* markerTreeWindow; - wxSashLayoutWindow* loggingWindow; - wxToolBar* tool_bar; - void Resize(int number); - wxNotebook *m_bookCtrl; - wxNotebook *m_bookCtrlbottom; - wxTextCtrl *m_textCtrlbrowse; - - private: - void TogStyle(int id, long flag); - - void DoSort(bool reverse = false); - - wxPanel *m_panel; - wxTextCtrl *m_textCtrl; - - void DoSetBold(bool bold = true); - -protected: - wxSashLayoutWindow* m_topWindow; - wxSashLayoutWindow* m_leftWindow2; - -DECLARE_EVENT_TABLE() -}; - -class OPJChildFrame: public wxMDIChildFrame -{ - public: - OPJCanvas *m_canvas; - OPJChildFrame(OPJFrame *parent, wxFileName fname, int winnumber, const wxString& title, const wxPoint& pos, const wxSize& size, const long style); - ~OPJChildFrame(void); - void OnActivate(wxActivateEvent& event); - /*void OnQuit(wxCommandEvent& WXUNUSED(event));*/ - void OnClose(wxCloseEvent& event); - void OnGotFocus(wxFocusEvent& event); - void OnLostFocus(wxFocusEvent& event); - OPJFrame *m_frame; - wxFileName m_fname; - int m_winnumber; - - unsigned long m_twidth, m_theight, m_tx, m_ty; - - DECLARE_EVENT_TABLE() -}; - -// frame and main menu ids -enum { - OPJFRAME_FILEEXIT = wxID_EXIT, - OPJFRAME_HELPABOUT = wxID_ABOUT, - OPJFRAME_FILEOPEN, - OPJFRAME_MEMORYOPEN, - OPJFRAME_FILESAVEAS, - OPJFRAME_FILETOGGLEB, - OPJFRAME_FILETOGGLEP, - OPJFRAME_FILETOGGLET, - OPJFRAME_VIEWZOOM, - OPJFRAME_VIEWFIT, - OPJFRAME_VIEWRELOAD, - OPJFRAME_VIEWPREVFRAME, - OPJFRAME_VIEWHOMEFRAME, - OPJFRAME_VIEWNEXTFRAME, - OPJFRAME_VIEWLESSLAYERS, - OPJFRAME_VIEWALLLAYERS, - OPJFRAME_VIEWMORELAYERS, - OPJFRAME_VIEWLESSRES, - OPJFRAME_VIEWFULLRES, - OPJFRAME_VIEWMORERES, - OPJFRAME_VIEWPREVCOMP, - OPJFRAME_VIEWALLCOMPS, - OPJFRAME_VIEWNEXTCOMP, - OPJFRAME_FILECLOSE, - OPJFRAME_SETSENCO, - OPJFRAME_SETSDECO, - - OPJFRAME_BROWSEWIN = 10000, - OPJFRAME_LOGWIN, - OPJFRAME_TOOLBAR, - - OPJFRAME_THREADLOGMSG, - OPJCANVAS_THREADSIGNAL -}; - - -// menu and control ids -enum -{ - TreeTest_Quit = wxID_EXIT, - TreeTest_About = wxID_ABOUT, - TreeTest_TogButtons = wxID_HIGHEST, - TreeTest_TogTwist, - TreeTest_TogLines, - TreeTest_TogEdit, - TreeTest_TogHideRoot, - TreeTest_TogRootLines, - TreeTest_TogBorder, - TreeTest_TogFullHighlight, - TreeTest_SetFgColour, - TreeTest_SetBgColour, - TreeTest_ResetStyle, - TreeTest_Highlight, - TreeTest_Dump, - TreeTest_DumpSelected, - TreeTest_Count, - TreeTest_CountRec, - TreeTest_Sort, - TreeTest_SortRev, - TreeTest_SetBold, - TreeTest_ClearBold, - TreeTest_Rename, - TreeTest_Delete, - TreeTest_DeleteChildren, - TreeTest_DeleteAll, - TreeTest_Recreate, - TreeTest_ToggleImages, - TreeTest_ToggleButtons, - TreeTest_SetImageSize, - TreeTest_ToggleSel, - TreeTest_CollapseAndReset, - TreeTest_EnsureVisible, - TreeTest_AddItem, - TreeTest_InsertItem, - TreeTest_IncIndent, - TreeTest_DecIndent, - TreeTest_IncSpacing, - TreeTest_DecSpacing, - TreeTest_ToggleIcon, - TreeTest_Select, - TreeTest_Unselect, - TreeTest_SelectRoot, - TreeTest_Ctrl = 1000, - BOTTOM_NOTEBOOK_ID, - LEFT_NOTEBOOK_ID -}; - -class OPJEncoThread : public wxThread -{ -public: - OPJEncoThread(OPJCanvas *canvas); - - // thread execution starts here - virtual void *Entry(); - - // called when the thread exits - whether it terminates normally or is - // stopped with Delete() (but not when it is Kill()ed!) - virtual void OnExit(); - - // write something to the text control - void WriteText(const wxString& text); - -public: - unsigned m_count; - OPJCanvas *m_canvas; -}; - -class OPJDecoThread : public wxThread -{ -public: - OPJDecoThread(OPJCanvas *canvas); - - // thread execution starts here - virtual void *Entry(); - - // called when the thread exits - whether it terminates normally or is - // stopped with Delete() (but not when it is Kill()ed!) - virtual void OnExit(); - - // write something to the text control - void WriteText(const wxString& text); - -public: - unsigned m_count; - OPJCanvas *m_canvas; -}; - -class OPJParseThread : public wxThread -{ -public: - OPJParseThread(OPJMarkerTree *tree, wxTreeItemId parentid = 0x00); - - // thread execution starts here - virtual void *Entry(); - - // called when the thread exits - whether it terminates normally or is - // stopped with Delete() (but not when it is Kill()ed!) - virtual void OnExit(); - - // write something to the text control - void WriteText(const wxString& text); - void LoadFile(wxFileName fname); - void ParseJ2KFile(wxFile *m_file, wxFileOffset offset, wxFileOffset length, wxTreeItemId parentid); - void ParseJP2File(wxFile *fileid, wxFileOffset filepoint, wxFileOffset filelimit, wxTreeItemId parentid); - - unsigned m_count; - OPJMarkerTree *m_tree; - wxTreeItemId m_parentid; - -private: - int jpeg2000parse(wxFile *fileid, wxFileOffset filepoint, wxFileOffset filelimit, - wxTreeItemId parentid, int level, char *scansign, unsigned long int *scanpoint); - int box_handler_function(int boxtype, wxFile *fileid, wxFileOffset filepoint, wxFileOffset filelimit, - wxTreeItemId parentid, int level, char *scansign, unsigned long int *scanpoint); - -}; - - -// 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: encoder -class OPJEncoderDialog: public wxPropertySheetDialog -{ -DECLARE_CLASS(OPJEncoderDialog) -public: - OPJEncoderDialog(wxWindow* parent, int dialogType); - ~OPJEncoderDialog(); - - wxBookCtrlBase* m_settingsNotebook; - - wxPanel* CreateMainSettingsPage(wxWindow* parent); - wxPanel* CreatePart1_1SettingsPage(wxWindow* parent); - wxPanel* CreatePart1_2SettingsPage(wxWindow* parent); -/* wxPanel* CreatePart3SettingsPage(wxWindow* parent);*/ - void OnEnableComm(wxCommandEvent& event); - void OnEnableIdx(wxCommandEvent& event); - void OnEnablePoc(wxCommandEvent& event); - void OnRadioQualityRate(wxCommandEvent& event); -#ifdef USE_JPWL - void OnEnableJPWL(wxCommandEvent& event); - wxPanel* CreatePart11SettingsPage(wxWindow* parent); - /*wxCheckBox *m_enablejpwlCheck;*/ - wxChoice *m_hprotChoice[MYJPWL_MAX_NO_TILESPECS]; - wxSpinCtrl *m_htileCtrl[MYJPWL_MAX_NO_TILESPECS]; - wxChoice *m_pprotChoice[MYJPWL_MAX_NO_TILESPECS]; - wxSpinCtrl *m_ptileCtrl[MYJPWL_MAX_NO_TILESPECS]; - wxSpinCtrl *m_ppackCtrl[MYJPWL_MAX_NO_TILESPECS]; - wxChoice *m_sensiChoice[MYJPWL_MAX_NO_TILESPECS]; - wxSpinCtrl *m_stileCtrl[MYJPWL_MAX_NO_TILESPECS]; - void OnHprotSelect(wxCommandEvent& event); - void OnPprotSelect(wxCommandEvent& event); - void OnSensiSelect(wxCommandEvent& event); -#endif // USE_JPWL - - wxTextCtrl *m_subsamplingCtrl, *m_originCtrl, *m_rateCtrl, *m_commentCtrl; - wxRadioButton *m_rateRadio, *m_qualityRadio; - wxTextCtrl *m_indexCtrl, *m_qualityCtrl, *m_cbsizeCtrl, *m_prsizeCtrl, *m_pocCtrl; - wxTextCtrl *m_tsizeCtrl, *m_toriginCtrl; - wxRadioBox *progressionBox; - wxCheckBox *m_enablecommCheck, *m_enableidxCheck, *m_mctCheck, *m_irrevCheck; - wxCheckBox *m_sopCheck, *m_ephCheck, *m_enablebypassCheck, *m_enableresetCheck, - *m_enablerestartCheck, *m_enablevscCheck, *m_enableertermCheck, *m_enablesegmarkCheck; - wxCheckBox *m_enablepocCheck, *m_enablejpwlCheck; - wxSpinCtrl *m_resolutionsCtrl; - -protected: - - enum { - OPJENCO_ENABLEJPWL = 100, - OPJENCO_RATEFACTOR, - OPJENCO_RATERADIO, - OPJENCO_QUALITYFACTOR, - OPJENCO_QUALITYRADIO, - OPJENCO_RESNUMBER, - OPJENCO_CODEBLOCKSIZE, - OPJENCO_PRECINCTSIZE, - OPJENCO_TILESIZE, - OPJENCO_PROGRESSION, - OPJENCO_SUBSAMPLING, - OPJENCO_ENABLESOP, - OPJENCO_ENABLEEPH, - OPJENCO_ENABLEBYPASS, - OPJENCO_ENABLERESET, - OPJENCO_ENABLERESTART, - OPJENCO_ENABLEVSC, - OPJENCO_ENABLEERTERM, - OPJENCO_ENABLESEGMARK, - OPJENCO_ENABLEPOC, - OPJENCO_ROICOMP, - OPJENCO_ROISHIFT, - OPJENCO_IMORIG, - OPJENCO_TILORIG, - OPJENCO_ENABLEMCT, - OPJENCO_ENABLEIRREV, - OPJENCO_ENABLEINDEX, - OPJENCO_INDEXNAME, - OPJENCO_POCSPEC, - OPJENCO_ENABLECOMM, - OPJENCO_COMMENTTEXT, - OPJENCO_HPROT, - OPJENCO_HTILE, - OPJENCO_PPROT, - OPJENCO_PTILE, - OPJENCO_PPACK, - OPJENCO_SENSI, - OPJENCO_STILE - }; - -DECLARE_EVENT_TABLE() -}; - -// Property sheet dialog: decoder -class OPJDecoderDialog: public wxPropertySheetDialog -{ -DECLARE_CLASS(OPJDecoderDialog) -public: - OPJDecoderDialog(wxWindow* parent, int dialogType); - ~OPJDecoderDialog(); - - wxBookCtrlBase* m_settingsNotebook; - wxCheckBox *m_enabledecoCheck, *m_enableparseCheck; - wxSpinCtrl *m_reduceCtrl, *m_layerCtrl, *m_numcompsCtrl; - wxRadioBox* m_resizeBox; - - void OnEnableDeco(wxCommandEvent& event); - - wxPanel* CreateMainSettingsPage(wxWindow* parent); - wxPanel* CreatePart1SettingsPage(wxWindow* parent); - wxPanel* CreatePart3SettingsPage(wxWindow* parent); -#ifdef USE_JPWL - void OnEnableJPWL(wxCommandEvent& event); - wxPanel* CreatePart11SettingsPage(wxWindow* parent); - wxSpinCtrl *m_expcompsCtrl, *m_maxtilesCtrl; - wxCheckBox *m_enablejpwlCheck; -#endif // USE_JPWL - wxSpinCtrl *m_framenumCtrl; - - -protected: - - enum { - OPJDECO_RESMETHOD = 100, - OPJDECO_REDUCEFACTOR, - OPJDECO_QUALITYLAYERS, - OPJDECO_NUMCOMPS, - OPJDECO_ENABLEDECO, - OPJDECO_ENABLEPARSE, - OPJDECO_ENABLEJPWL, - OPJDECO_EXPCOMPS, - OPJDECO_MAXTILES, - OPJDECO_FRAMENUM - }; - -DECLARE_EVENT_TABLE() -}; - -#endif //__OPJ_VIEWER_H__ - - - +/* + * Copyright (c) 2007, Digital Signal Processing Laboratory, Università degli studi di Perugia (UPG), Italy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are 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. + */ +///////////////////////////////////////////////////////////////////////////// +// Name: sashtest.h +// Purpose: Layout window/sash sample +// Author: Julian Smart +// Modified by: +// Created: 04/01/98 +// RCS-ID: $Id: sashtest.h,v 1.5 2005/06/02 12:04:24 JS Exp $ +// Copyright: (c) Julian Smart +// Licence: wxWindows license +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// +// Name: treectrl.h +// Purpose: wxTreeCtrl sample +// Author: Julian Smart +// Modified by: +// Created: 04/01/98 +// RCS-ID: $Id: treetest.h,v 1.50 2006/11/04 11:26:51 VZ Exp $ +// 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__ + +// For compilers that support precompilation, includes "wx/wx.h". +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + +#ifndef WX_PRECOMP +#include "wx/wx.h" +#include "wx/mdi.h" +#endif + +#include "wx/toolbar.h" +#include "wx/laywin.h" +#include "wx/treectrl.h" + +#include "icon1.xpm" +#include "icon2.xpm" +#include "icon3.xpm" +#include "icon4.xpm" +#include "icon5.xpm" + +#include "wx/filedlg.h" +#include "wx/toolbar.h" +#include +#include +#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 + +#include + +#include "wx/toolbar.h" +#include "wx/artprov.h" + +#include "libopenjpeg/openjpeg.h" + +//#include "imagj2k.h" +//#include "imagjp2.h" +//#include "imagmj2.h" +#include "imagjpeg2000.h" +#ifdef USE_MXF +#include "imagmxf.h" +#endif // USE_MXF + +#ifdef __WXMSW__ +typedef unsigned __int64 int8byte; +#endif // __WXMSW__ + +#ifdef __WXGTK__ +typedef unsigned long long int8byte; +#endif // __WXGTK__ + +#define USE_GENERIC_TREECTRL 0 +#define USE_PENCIL_ON_CANVAS 0 + +#if USE_GENERIC_TREECTRL +#include "wx/generic/treectlg.h" +#ifndef wxTreeCtrl +#define wxTreeCtrl wxGenericTreeCtrl +#define sm_classwxTreeCtrl sm_classwxGenericTreeCtrl +#endif +#endif + +#define OPJ_APPLICATION wxT("OPJViewer") +#define OPJ_APPLICATION_NAME wxT("OpenJPEG Viewer") +#define OPJ_APPLICATION_VERSION wxT("0.4 beta") +#define OPJ_APPLICATION_TITLEBAR OPJ_APPLICATION_NAME wxT(" ") OPJ_APPLICATION_VERSION +#define OPJ_APPLICATION_COPYRIGHT wxT("(C) 2007-2008, Giuseppe Baruffa") +#define OPJ_APPLICATION_VENDOR wxT("OpenJPEG") + +#ifdef __WXMSW__ +#define OPJ_APPLICATION_PLATFORM wxT("Windows") +#endif + +#ifdef __WXGTK__ +#define OPJ_APPLICATION_PLATFORM wxT("Linux") +#endif + +#define OPJ_FRAME_WIDTH 800 +#define OPJ_FRAME_HEIGHT 600 + +#define OPJ_BROWSER_WIDTH 300 +#define OPJ_PEEKER_HEIGHT 130 + +#define OPJ_CANVAS_BORDER 10 +#define OPJ_CANVAS_COLOUR *wxWHITE + + + +#ifdef USE_JPWL + +//#define MYJPWL_MAX_NO_TILESPECS JPWL_MAX_NO_TILESPECS +#define MYJPWL_MAX_NO_TILESPECS 4 + +#endif // USE_JPWL + + +class OPJDecoThread; +class OPJEncoThread; +class OPJParseThread; +WX_DEFINE_ARRAY_PTR(wxThread *, wxArrayThread); +class OPJChildFrame; + +////////////////////////////////// +// this is our main application // +////////////////////////////////// +class OPJViewerApp: public wxApp +{ + // public methods and variables + public: + + // class constructor + OPJViewerApp() { m_showImages = true; m_showButtons = false; } + + // other methods + bool OnInit(void); + int OnExit(void); + void SetShowImages(bool show) { m_showImages = show; } + bool ShowImages() const { return m_showImages; } + void ShowCmdLine(const wxCmdLineParser& parser); + + // all the threads currently alive - as soon as the thread terminates, it's + // removed from the array + wxArrayThread m_deco_threads, m_parse_threads, m_enco_threads; + + // crit section protects access to all of the arrays below + wxCriticalSection m_deco_critsect, m_parse_critsect, m_enco_critsect; + + // semaphore used to wait for the threads to exit, see OPJFrame::OnQuit() + wxSemaphore m_deco_semAllDone, m_parse_semAllDone, m_enco_semAllDone; + + // the last exiting thread should post to m_semAllDone if this is true + // (protected by the same m_critsect) + bool m_deco_waitingUntilAllDone, m_parse_waitingUntilAllDone, m_enco_waitingUntilAllDone; + + // the list of all filenames written in the command line + wxArrayString m_filelist; + + // displaying engine parameters + int m_resizemethod; + + // decoding engine parameters + bool m_enabledeco, m_enableparse; + int m_reducefactor, m_qualitylayers, m_components, m_framenum; +#ifdef USE_JPWL + bool m_enablejpwl, m_enablejpwle; + int m_expcomps, m_maxtiles; +#endif // USE_JPWL + int m_framewidth, m_frameheight; + + // encoding engine parameters + wxString m_subsampling, m_origin, m_rates, m_comment, m_index, m_quality; + wxString m_cbsize, m_prsize, m_tsize, m_torigin, m_poc; + bool m_enablecomm, m_enableidx, m_multicomp, m_irreversible, m_enablesop, m_enableeph; + bool m_enablebypass, m_enablereset, m_enablerestart, m_enablevsc, m_enableerterm; + bool m_enablesegmark, m_enablepoc; + bool m_enablequality; + int m_resolutions, m_progression; +#ifdef USE_JPWL + int m_hprotsel[MYJPWL_MAX_NO_TILESPECS], m_pprotsel[MYJPWL_MAX_NO_TILESPECS]; + int m_htileval[MYJPWL_MAX_NO_TILESPECS], m_ptileval[MYJPWL_MAX_NO_TILESPECS], + m_ppackval[MYJPWL_MAX_NO_TILESPECS]; + int m_sensisel[MYJPWL_MAX_NO_TILESPECS], m_stileval[MYJPWL_MAX_NO_TILESPECS]; +#endif // USE_JPWL + + // some layout settings + bool m_showtoolbar, m_showbrowser, m_showpeeker; + int m_browserwidth, m_peekerheight; + + // application configuration + wxConfig *OPJconfig; + + // private methods and variables + private: + bool m_showImages, m_showButtons; + +}; + +DECLARE_APP(OPJViewerApp) + +/////////////////////////////////////////// +// this canvas is used to draw the image // +/////////////////////////////////////////// +class OPJCanvas: public wxScrolledWindow +{ + // public methods and variables + public: + + // class constructor + OPJCanvas(wxFileName fname, wxWindow *parent, const wxPoint& pos, const wxSize& size); + + virtual void OnDraw(wxDC& dc); + void OnEvent(wxMouseEvent& event); + void WriteText(const wxString& text) { +#ifndef __WXGTK__ + wxMutexGuiEnter(); +#endif //__WXGTK__ + wxLogMessage(text); +#ifndef __WXGTK__ + wxMutexGuiLeave(); +#endif //__WXGTK__ + } + + void OnThreadSignal(wxCommandEvent& event); + + OPJDecoThread *CreateDecoThread(void); + OPJEncoThread *CreateEncoThread(void); + + + OPJChildFrame *m_childframe; + + wxBitmap m_image, m_image100; + wxFileName m_fname, m_savename; + long m_zooml; + + DECLARE_EVENT_TABLE() +}; + +/////////////////////////////////////////////////// +// the data associated to each tree leaf or node // +/////////////////////////////////////////////////// +class OPJMarkerData : public wxTreeItemData +{ + // public methods and variables + public: + + // class constructor + 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; } + + void ShowInfo(wxTreeCtrl *tree); + const wxChar *GetDesc1() const { return m_desc.c_str(); } + const wxChar *GetDesc2() const { return m_filestring.c_str(); } + wxFileOffset m_start, m_length; + wxString m_desc; + + // private methods and variables + private: + wxString m_filestring; +}; + + +class OPJMarkerTree : public wxTreeCtrl +{ +public: + enum + { + TreeCtrlIcon_File, + TreeCtrlIcon_FileSelected, + TreeCtrlIcon_Folder, + TreeCtrlIcon_FolderSelected, + TreeCtrlIcon_FolderOpened + }; + + OPJMarkerTree() { }; + OPJMarkerTree(wxWindow *parent, OPJChildFrame *subframe, wxFileName fname, wxString name, const wxWindowID id, + const wxPoint& pos, const wxSize& size, + long style); + virtual ~OPJMarkerTree(){}; + OPJParseThread *CreateParseThread(wxTreeItemId parentid = 0x00, OPJChildFrame *subframe = NULL); + void WriteText(const wxString& text) { wxMutexGuiEnter(); wxLogMessage(text); wxMutexGuiLeave(); } + + wxFileName m_fname; + wxTextCtrl *m_peektextCtrl; + OPJChildFrame *m_childframe; + + /*void OnBeginDrag(wxTreeEvent& event); + void OnBeginRDrag(wxTreeEvent& event); + void OnEndDrag(wxTreeEvent& event);*/ + /*void OnBeginLabelEdit(wxTreeEvent& event); + void OnEndLabelEdit(wxTreeEvent& event);*/ + /*void OnDeleteItem(wxTreeEvent& event);*/ + /*void OnContextMenu(wxContextMenuEvent& event);*/ + void OnItemMenu(wxTreeEvent& event); + /*void OnGetInfo(wxTreeEvent& event); + void OnSetInfo(wxTreeEvent& event);*/ + /*void OnItemExpanded(wxTreeEvent& event);*/ + void OnItemExpanding(wxTreeEvent& event); + /*void OnItemCollapsed(wxTreeEvent& event); + void OnItemCollapsing(wxTreeEvent& event);*/ + void OnSelChanged(wxTreeEvent& event); + /*void OnSelChanging(wxTreeEvent& event);*/ + /*void OnTreeKeyDown(wxTreeEvent& event);*/ + /*void OnItemActivated(wxTreeEvent& event);*/ + /*void OnItemRClick(wxTreeEvent& event);*/ + /*void OnRMouseDown(wxMouseEvent& event); + void OnRMouseUp(wxMouseEvent& event); + void OnRMouseDClick(wxMouseEvent& event);*/ + /*void GetItemsRecursively(const wxTreeItemId& idParent, + wxTreeItemIdValue cookie = 0);*/ + + void CreateImageList(int size = 16); + void CreateButtonsImageList(int size = 11); + + /*void AddTestItemsToTree(size_t numChildren, size_t depth);*/ + /*void DoSortChildren(const wxTreeItemId& item, bool reverse = false) + { m_reverseSort = reverse; wxTreeCtrl::SortChildren(item); }*/ + /*void DoEnsureVisible() { if (m_lastItem.IsOk()) EnsureVisible(m_lastItem); }*/ + /*void DoToggleIcon(const wxTreeItemId& item);*/ + /*void ShowMenu(wxTreeItemId id, const wxPoint& pt);*/ + + int ImageSize(void) const { return m_imageSize; } + + void SetLastItem(wxTreeItemId id) { m_lastItem = id; } + +protected: + /*virtual int OnCompareItems(const wxTreeItemId& i1, const wxTreeItemId& i2);*/ + + // is this the test item which we use in several event handlers? + /*bool IsTestItem(const wxTreeItemId& item) + { + // the test item is the first child folder + return GetItemParent(item) == GetRootItem() && !GetPrevSibling(item); + }*/ + +private: + /*void AddItemsRecursively(const wxTreeItemId& idParent, + size_t nChildren, + size_t depth, + size_t folder);*/ + + void LogEvent(const wxChar *name, const wxTreeEvent& event); + + int m_imageSize; // current size of images + bool m_reverseSort; // flag for OnCompareItems + wxTreeItemId m_lastItem, // for OnEnsureVisible() + m_draggedItem; // item being dragged right now + + // NB: due to an ugly wxMSW hack you _must_ use DECLARE_DYNAMIC_CLASS() + // if you want your overloaded OnCompareItems() to be called. + // OTOH, if you don't want it you may omit the next line - this will + // make default (alphabetical) sorting much faster under wxMSW. + DECLARE_DYNAMIC_CLASS(OPJMarkerTree) + DECLARE_EVENT_TABLE() +}; + +// this hash map stores all the trees of currently opened images, with an integer key +WX_DECLARE_HASH_MAP(int, OPJMarkerTree*, wxIntegerHash, wxIntegerEqual, OPJMarkerTreeHash); + +// this hash map stores all the children of currently opened images, with an integer key +WX_DECLARE_HASH_MAP(int, OPJChildFrame*, wxIntegerHash, wxIntegerEqual, OPJChildFrameHash); + +// Define a new frame +class OPJFrame: public wxMDIParentFrame +{ + public: + + OPJFrame(wxWindow *parent, const wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, const long style); + + ~OPJFrame(void); + void OnSize(wxSizeEvent& WXUNUSED(event)); + void OnAbout(wxCommandEvent& WXUNUSED(event)); + void OnFileOpen(wxCommandEvent& WXUNUSED(event)); + void OnFileSaveAs(wxCommandEvent& WXUNUSED(event)); + void OnMemoryOpen(wxCommandEvent& WXUNUSED(event)); + void OnQuit(wxCommandEvent& WXUNUSED(event)); + void OnClose(wxCommandEvent& WXUNUSED(event)); + void OnZoom(wxCommandEvent& WXUNUSED(event)); + void OnFit(wxCommandEvent& event); + void OnToggleBrowser(wxCommandEvent& WXUNUSED(event)); + void OnTogglePeeker(wxCommandEvent& WXUNUSED(event)); + void OnToggleToolbar(wxCommandEvent& WXUNUSED(event)); + void OnReload(wxCommandEvent& event); + void OnPrevFrame(wxCommandEvent& event); + void OnHomeFrame(wxCommandEvent& event); + void OnNextFrame(wxCommandEvent& event); + void OnLessLayers(wxCommandEvent& event); + void OnAllLayers(wxCommandEvent& event); + void OnMoreLayers(wxCommandEvent& event); + void OnLessRes(wxCommandEvent& event); + void OnFullRes(wxCommandEvent& event); + void OnMoreRes(wxCommandEvent& event); + void OnPrevComp(wxCommandEvent& event); + void OnAllComps(wxCommandEvent& event); + void OnNextComp(wxCommandEvent& event); + void OnSetsEnco(wxCommandEvent& event); + void OnSetsDeco(wxCommandEvent& event); + void OnSashDrag(wxSashEvent& event); + void OpenFiles(wxArrayString paths, wxArrayString filenames); + void SaveFile(wxArrayString paths, wxArrayString filenames); + void OnNotebook(wxNotebookEvent& event); + void Rescale(int scale, OPJChildFrame *child); + void OnThreadLogmsg(wxCommandEvent& event); + + OPJMarkerTreeHash m_treehash; + OPJChildFrameHash m_childhash; + wxSashLayoutWindow* markerTreeWindow; + wxSashLayoutWindow* loggingWindow; + wxToolBar* tool_bar; + void Resize(int number); + wxNotebook *m_bookCtrl; + wxNotebook *m_bookCtrlbottom; + wxTextCtrl *m_textCtrlbrowse; + + private: + void TogStyle(int id, long flag); + + void DoSort(bool reverse = false); + + wxPanel *m_panel; + wxTextCtrl *m_textCtrl; + + void DoSetBold(bool bold = true); + +protected: + wxSashLayoutWindow* m_topWindow; + wxSashLayoutWindow* m_leftWindow2; + +DECLARE_EVENT_TABLE() +}; + +class OPJChildFrame: public wxMDIChildFrame +{ + public: + OPJCanvas *m_canvas; + OPJChildFrame(OPJFrame *parent, wxFileName fname, int winnumber, const wxString& title, const wxPoint& pos, const wxSize& size, const long style); + ~OPJChildFrame(void); + void OnActivate(wxActivateEvent& event); + /*void OnQuit(wxCommandEvent& WXUNUSED(event));*/ + void OnClose(wxCloseEvent& event); + void OnGotFocus(wxFocusEvent& event); + void OnLostFocus(wxFocusEvent& event); + OPJFrame *m_frame; + wxFileName m_fname; + int m_winnumber; + + unsigned long m_twidth, m_theight, m_tx, m_ty; + + DECLARE_EVENT_TABLE() +}; + +// frame and main menu ids +enum { + OPJFRAME_FILEEXIT = wxID_EXIT, + OPJFRAME_HELPABOUT = wxID_ABOUT, + OPJFRAME_FILEOPEN, + OPJFRAME_MEMORYOPEN, + OPJFRAME_FILESAVEAS, + OPJFRAME_FILETOGGLEB, + OPJFRAME_FILETOGGLEP, + OPJFRAME_FILETOGGLET, + OPJFRAME_VIEWZOOM, + OPJFRAME_VIEWFIT, + OPJFRAME_VIEWRELOAD, + OPJFRAME_VIEWPREVFRAME, + OPJFRAME_VIEWHOMEFRAME, + OPJFRAME_VIEWNEXTFRAME, + OPJFRAME_VIEWLESSLAYERS, + OPJFRAME_VIEWALLLAYERS, + OPJFRAME_VIEWMORELAYERS, + OPJFRAME_VIEWLESSRES, + OPJFRAME_VIEWFULLRES, + OPJFRAME_VIEWMORERES, + OPJFRAME_VIEWPREVCOMP, + OPJFRAME_VIEWALLCOMPS, + OPJFRAME_VIEWNEXTCOMP, + OPJFRAME_FILECLOSE, + OPJFRAME_SETSENCO, + OPJFRAME_SETSDECO, + + OPJFRAME_BROWSEWIN = 10000, + OPJFRAME_LOGWIN, + OPJFRAME_TOOLBAR, + + OPJFRAME_THREADLOGMSG, + OPJCANVAS_THREADSIGNAL +}; + + +// menu and control ids +enum +{ + TreeTest_Quit = wxID_EXIT, + TreeTest_About = wxID_ABOUT, + TreeTest_TogButtons = wxID_HIGHEST, + TreeTest_TogTwist, + TreeTest_TogLines, + TreeTest_TogEdit, + TreeTest_TogHideRoot, + TreeTest_TogRootLines, + TreeTest_TogBorder, + TreeTest_TogFullHighlight, + TreeTest_SetFgColour, + TreeTest_SetBgColour, + TreeTest_ResetStyle, + TreeTest_Highlight, + TreeTest_Dump, + TreeTest_DumpSelected, + TreeTest_Count, + TreeTest_CountRec, + TreeTest_Sort, + TreeTest_SortRev, + TreeTest_SetBold, + TreeTest_ClearBold, + TreeTest_Rename, + TreeTest_Delete, + TreeTest_DeleteChildren, + TreeTest_DeleteAll, + TreeTest_Recreate, + TreeTest_ToggleImages, + TreeTest_ToggleButtons, + TreeTest_SetImageSize, + TreeTest_ToggleSel, + TreeTest_CollapseAndReset, + TreeTest_EnsureVisible, + TreeTest_AddItem, + TreeTest_InsertItem, + TreeTest_IncIndent, + TreeTest_DecIndent, + TreeTest_IncSpacing, + TreeTest_DecSpacing, + TreeTest_ToggleIcon, + TreeTest_Select, + TreeTest_Unselect, + TreeTest_SelectRoot, + TreeTest_Ctrl = 1000, + BOTTOM_NOTEBOOK_ID, + LEFT_NOTEBOOK_ID +}; + +class OPJEncoThread : public wxThread +{ +public: + OPJEncoThread(OPJCanvas *canvas); + + // thread execution starts here + virtual void *Entry(); + + // called when the thread exits - whether it terminates normally or is + // stopped with Delete() (but not when it is Kill()ed!) + virtual void OnExit(); + + // write something to the text control + void WriteText(const wxString& text); + +public: + unsigned m_count; + OPJCanvas *m_canvas; +}; + +class OPJDecoThread : public wxThread +{ +public: + OPJDecoThread(OPJCanvas *canvas); + + // thread execution starts here + virtual void *Entry(); + + // called when the thread exits - whether it terminates normally or is + // stopped with Delete() (but not when it is Kill()ed!) + virtual void OnExit(); + + // write something to the text control + void WriteText(const wxString& text); + +public: + unsigned m_count; + OPJCanvas *m_canvas; +}; + +class OPJParseThread : public wxThread +{ +public: + OPJParseThread(OPJMarkerTree *tree, wxTreeItemId parentid = 0x00); + + // thread execution starts here + virtual void *Entry(); + + // called when the thread exits - whether it terminates normally or is + // stopped with Delete() (but not when it is Kill()ed!) + virtual void OnExit(); + + // write something to the text control + void WriteText(const wxString& text); + void LoadFile(wxFileName fname); + void ParseJ2KFile(wxFile *m_file, wxFileOffset offset, wxFileOffset length, wxTreeItemId parentid); + void ParseJP2File(wxFile *fileid, wxFileOffset filepoint, wxFileOffset filelimit, wxTreeItemId parentid); + + unsigned m_count; + OPJMarkerTree *m_tree; + wxTreeItemId m_parentid; + +private: + int jpeg2000parse(wxFile *fileid, wxFileOffset filepoint, wxFileOffset filelimit, + wxTreeItemId parentid, int level, char *scansign, unsigned long int *scanpoint); + int box_handler_function(int boxtype, wxFile *fileid, wxFileOffset filepoint, wxFileOffset filelimit, + wxTreeItemId parentid, int level, char *scansign, unsigned long int *scanpoint); + +}; + + +// 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: encoder +class OPJEncoderDialog: public wxPropertySheetDialog +{ +DECLARE_CLASS(OPJEncoderDialog) +public: + OPJEncoderDialog(wxWindow* parent, int dialogType); + ~OPJEncoderDialog(); + + wxBookCtrlBase* m_settingsNotebook; + + wxPanel* CreateMainSettingsPage(wxWindow* parent); + wxPanel* CreatePart1_1SettingsPage(wxWindow* parent); + wxPanel* CreatePart1_2SettingsPage(wxWindow* parent); +/* wxPanel* CreatePart3SettingsPage(wxWindow* parent);*/ + void OnEnableComm(wxCommandEvent& event); + void OnEnableIdx(wxCommandEvent& event); + void OnEnablePoc(wxCommandEvent& event); + void OnRadioQualityRate(wxCommandEvent& event); +#ifdef USE_JPWL + void OnEnableJPWL(wxCommandEvent& event); + wxPanel* CreatePart11SettingsPage(wxWindow* parent); + /*wxCheckBox *m_enablejpwlCheck;*/ + wxChoice *m_hprotChoice[MYJPWL_MAX_NO_TILESPECS]; + wxSpinCtrl *m_htileCtrl[MYJPWL_MAX_NO_TILESPECS]; + wxChoice *m_pprotChoice[MYJPWL_MAX_NO_TILESPECS]; + wxSpinCtrl *m_ptileCtrl[MYJPWL_MAX_NO_TILESPECS]; + wxSpinCtrl *m_ppackCtrl[MYJPWL_MAX_NO_TILESPECS]; + wxChoice *m_sensiChoice[MYJPWL_MAX_NO_TILESPECS]; + wxSpinCtrl *m_stileCtrl[MYJPWL_MAX_NO_TILESPECS]; + void OnHprotSelect(wxCommandEvent& event); + void OnPprotSelect(wxCommandEvent& event); + void OnSensiSelect(wxCommandEvent& event); +#endif // USE_JPWL + + wxTextCtrl *m_subsamplingCtrl, *m_originCtrl, *m_rateCtrl, *m_commentCtrl; + wxRadioButton *m_rateRadio, *m_qualityRadio; + wxTextCtrl *m_indexCtrl, *m_qualityCtrl, *m_cbsizeCtrl, *m_prsizeCtrl, *m_pocCtrl; + wxTextCtrl *m_tsizeCtrl, *m_toriginCtrl; + wxRadioBox *progressionBox; + wxCheckBox *m_enablecommCheck, *m_enableidxCheck, *m_mctCheck, *m_irrevCheck; + wxCheckBox *m_sopCheck, *m_ephCheck, *m_enablebypassCheck, *m_enableresetCheck, + *m_enablerestartCheck, *m_enablevscCheck, *m_enableertermCheck, *m_enablesegmarkCheck; + wxCheckBox *m_enablepocCheck, *m_enablejpwlCheck; + wxSpinCtrl *m_resolutionsCtrl; + +protected: + + enum { + OPJENCO_ENABLEJPWL = 100, + OPJENCO_RATEFACTOR, + OPJENCO_RATERADIO, + OPJENCO_QUALITYFACTOR, + OPJENCO_QUALITYRADIO, + OPJENCO_RESNUMBER, + OPJENCO_CODEBLOCKSIZE, + OPJENCO_PRECINCTSIZE, + OPJENCO_TILESIZE, + OPJENCO_PROGRESSION, + OPJENCO_SUBSAMPLING, + OPJENCO_ENABLESOP, + OPJENCO_ENABLEEPH, + OPJENCO_ENABLEBYPASS, + OPJENCO_ENABLERESET, + OPJENCO_ENABLERESTART, + OPJENCO_ENABLEVSC, + OPJENCO_ENABLEERTERM, + OPJENCO_ENABLESEGMARK, + OPJENCO_ENABLEPOC, + OPJENCO_ROICOMP, + OPJENCO_ROISHIFT, + OPJENCO_IMORIG, + OPJENCO_TILORIG, + OPJENCO_ENABLEMCT, + OPJENCO_ENABLEIRREV, + OPJENCO_ENABLEINDEX, + OPJENCO_INDEXNAME, + OPJENCO_POCSPEC, + OPJENCO_ENABLECOMM, + OPJENCO_COMMENTTEXT, + OPJENCO_HPROT, + OPJENCO_HTILE, + OPJENCO_PPROT, + OPJENCO_PTILE, + OPJENCO_PPACK, + OPJENCO_SENSI, + OPJENCO_STILE + }; + +DECLARE_EVENT_TABLE() +}; + +// Property sheet dialog: decoder +class OPJDecoderDialog: public wxPropertySheetDialog +{ +DECLARE_CLASS(OPJDecoderDialog) +public: + OPJDecoderDialog(wxWindow* parent, int dialogType); + ~OPJDecoderDialog(); + + wxBookCtrlBase* m_settingsNotebook; + wxCheckBox *m_enabledecoCheck, *m_enableparseCheck; + wxSpinCtrl *m_reduceCtrl, *m_layerCtrl, *m_numcompsCtrl; + wxRadioBox* m_resizeBox; + + void OnEnableDeco(wxCommandEvent& event); + + wxPanel* CreateMainSettingsPage(wxWindow* parent); + wxPanel* CreatePart1SettingsPage(wxWindow* parent); + wxPanel* CreatePart3SettingsPage(wxWindow* parent); +#ifdef USE_JPWL + void OnEnableJPWL(wxCommandEvent& event); + wxPanel* CreatePart11SettingsPage(wxWindow* parent); + wxSpinCtrl *m_expcompsCtrl, *m_maxtilesCtrl; + wxCheckBox *m_enablejpwlCheck; +#endif // USE_JPWL + wxSpinCtrl *m_framenumCtrl; + + +protected: + + enum { + OPJDECO_RESMETHOD = 100, + OPJDECO_REDUCEFACTOR, + OPJDECO_QUALITYLAYERS, + OPJDECO_NUMCOMPS, + OPJDECO_ENABLEDECO, + OPJDECO_ENABLEPARSE, + OPJDECO_ENABLEJPWL, + OPJDECO_EXPCOMPS, + OPJDECO_MAXTILES, + OPJDECO_FRAMENUM + }; + +DECLARE_EVENT_TABLE() +}; + +#endif //__OPJ_VIEWER_H__ + + + diff --git a/applications/OPJViewer/source/OPJViewer.rc b/applications/OPJViewer/source/OPJViewer.rc index fb5a5def..82af985b 100644 --- a/applications/OPJViewer/source/OPJViewer.rc +++ b/applications/OPJViewer/source/OPJViewer.rc @@ -1,3 +1,3 @@ -OPJChild16 ICON OPJChild.ico -OPJViewer16 ICON OPJViewer.ico +OPJChild16 ICON OPJChild.ico +OPJViewer16 ICON OPJViewer.ico #include "wx/msw/wx.rc" \ No newline at end of file diff --git a/applications/OPJViewer/source/OPJViewer16.xpm b/applications/OPJViewer/source/OPJViewer16.xpm index 27e522b1..7c65acb3 100644 --- a/applications/OPJViewer/source/OPJViewer16.xpm +++ b/applications/OPJViewer/source/OPJViewer16.xpm @@ -1,26 +1,26 @@ -/* XPM */ -static char *OPJViewer16[] = { -/* columns rows colors chars-per-pixel */ -"16 16 4 1", -" c black", -". c #800000", -"X c red", -"o c None", -/* pixels */ -"oooooooooooooooo", -"ooo.XXXXoooooooo", -"ooXXoo .Xooooooo", -"o..oooo .ooooooo", -"oX.oooo ooooooo", -"oX.oooo .ooooooo", -"oXXoooo .ooooooo", -"o.XXoo .oooooooo", -"oo.XXXXooooooooo", -"ooooooooo.Xo .oo", -"ooooooooo X. ooo", -"oooooooooo...ooo", -"oooooooooo XXooo", -"oooooooooo .Xooo", -"oooooooooooooooo", -"oooooooooooooooo" -}; +/* XPM */ +static char *OPJViewer16[] = { +/* columns rows colors chars-per-pixel */ +"16 16 4 1", +" c black", +". c #800000", +"X c red", +"o c None", +/* pixels */ +"oooooooooooooooo", +"ooo.XXXXoooooooo", +"ooXXoo .Xooooooo", +"o..oooo .ooooooo", +"oX.oooo ooooooo", +"oX.oooo .ooooooo", +"oXXoooo .ooooooo", +"o.XXoo .oooooooo", +"oo.XXXXooooooooo", +"ooooooooo.Xo .oo", +"ooooooooo X. ooo", +"oooooooooo...ooo", +"oooooooooo XXooo", +"oooooooooo .Xooo", +"oooooooooooooooo", +"oooooooooooooooo" +}; diff --git a/applications/OPJViewer/source/about_htm.h b/applications/OPJViewer/source/about_htm.h index c39fdc59..79a859d8 100644 --- a/applications/OPJViewer/source/about_htm.h +++ b/applications/OPJViewer/source/about_htm.h @@ -1,54 +1,54 @@ -wxString htmlaboutpage = wxT( -"" -"" -"" -"" -"" -"" -"" -"" -"" -"" -"" -"" -"" -"" -"" -"" -"" -"" -"" -"
" -"

" -"
" -"" -OPJ_APPLICATION " " OPJ_APPLICATION_VERSION -"
" -"A JPEG 2000 image viewer
" -"" OPJ_APPLICATION_PLATFORM " version" -"
" -"
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.


" -"* Build: ") -#include "build.h" -wxT(", " __DATE__ ", " __TIME__ "
") -wxT("* " wxVERSION_STRING "
") -wxT("* OpenJPEG " OPENJPEG_VERSION " (") -#ifdef USE_JPWL -wxT("JPWL ") -#endif // USE_JPWL -#ifdef USE_JPSEC -wxT("JPSEC ") -#endif // USE_JPSEC -wxT(")
") -#ifdef USE_MXF -wxT("* MXFLib " MXFLIB_VERSION_MAJOR "." MXFLIB_VERSION_MINOR "." MXFLIB_VERSION_TWEAK " (" MXFLIB_VERSION_BUILD ")
") -#endif // USE_MXF -wxT("
" -"OpenJPEG is © 2002-2008 TELE - Universite' Catholique de Louvain
" -"OPJViewer is © 2007-2008 DSPLab - Universita' degli studi di Perugia" -"
" -"" -"" -); +wxString htmlaboutpage = wxT( +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"
" +"

" +"
" +"" +OPJ_APPLICATION " " OPJ_APPLICATION_VERSION +"
" +"A JPEG 2000 image viewer
" +"" OPJ_APPLICATION_PLATFORM " version" +"
" +"
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.


" +"* Build: ") +#include "build.h" +wxT(", " __DATE__ ", " __TIME__ "
") +wxT("* " wxVERSION_STRING "
") +wxT("* OpenJPEG " OPENJPEG_VERSION " (") +#ifdef USE_JPWL +wxT("JPWL ") +#endif // USE_JPWL +#ifdef USE_JPSEC +wxT("JPSEC ") +#endif // USE_JPSEC +wxT(")
") +#ifdef USE_MXF +wxT("* MXFLib " MXFLIB_VERSION_MAJOR "." MXFLIB_VERSION_MINOR "." MXFLIB_VERSION_TWEAK " (" MXFLIB_VERSION_BUILD ")
") +#endif // USE_MXF +wxT("
" +"OpenJPEG is © 2002-2008 TELE - Universite' Catholique de Louvain
" +"OPJViewer is © 2007-2008 DSPLab - Universita' degli studi di Perugia" +"
" +"" +"" +); diff --git a/applications/OPJViewer/source/build.h b/applications/OPJViewer/source/build.h index 9858dffe..f0f072c8 100644 --- a/applications/OPJViewer/source/build.h +++ b/applications/OPJViewer/source/build.h @@ -1 +1 @@ -wxT("491") +wxT("491") diff --git a/applications/OPJViewer/source/imagjpeg2000.cpp b/applications/OPJViewer/source/imagjpeg2000.cpp index 66e1146b..ee2aa74d 100644 --- a/applications/OPJViewer/source/imagjpeg2000.cpp +++ b/applications/OPJViewer/source/imagjpeg2000.cpp @@ -1,1464 +1,1464 @@ -/* - * Copyright (c) 2007, Digital Signal Processing Laboratory, Università degli studi di Perugia (UPG), Italy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are 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. - */ -///////////////////////////////////////////////////////////////////////////// -// Name: imagjpeg2000.cpp -// Purpose: wxImage JPEG 2000 family file format handler -// Author: Giuseppe Baruffa - based on imagjpeg.cpp, Vaclav Slavik -// RCS-ID: $Id: imagjpeg2000.cpp,v 0.00 2008/01/31 10:58:00 MW Exp $ -// Copyright: (c) Giuseppe Baruffa -// Licence: wxWindows licence -///////////////////////////////////////////////////////////////////////////// - -// For compilers that support precompilation, includes "wx.h". -#include "wx/wxprec.h" - -#ifdef __BORLANDC__ - #pragma hdrstop -#endif - -#if wxUSE_IMAGE && wxUSE_LIBOPENJPEG - -#include "imagjpeg2000.h" - -#ifndef WX_PRECOMP - #include "wx/log.h" - #include "wx/app.h" - #include "wx/intl.h" - #include "wx/bitmap.h" - #include "wx/module.h" -#endif - -#include "libopenjpeg/openjpeg.h" - -#include "wx/filefn.h" -#include "wx/wfstream.h" - -// ---------------------------------------------------------------------------- -// types -// ---------------------------------------------------------------------------- - - -//----------------------------------------------------------------------------- -// wxJPEG2000Handler -//----------------------------------------------------------------------------- - -IMPLEMENT_DYNAMIC_CLASS(wxJPEG2000Handler,wxImageHandler) - -#if wxUSE_STREAMS - -//------------- JPEG 2000 Data Source Manager - -#define J2K_CFMT 0 -#define JP2_CFMT 1 -#define JPT_CFMT 2 -#define MJ2_CFMT 3 -#define PXM_DFMT 0 -#define PGX_DFMT 1 -#define BMP_DFMT 2 -#define YUV_DFMT 3 - -#define MAX_MESSAGE_LEN 200 - -/* check file type */ -int -jpeg2000familytype(unsigned char *hdr, int hdr_len) -{ - // check length - if (hdr_len < 24) - return -1; - - // check format - if (hdr[0] == 0x00 && - hdr[1] == 0x00 && - hdr[2] == 0x00 && - hdr[3] == 0x0C && - hdr[4] == 0x6A && - hdr[5] == 0x50 && - hdr[6] == 0x20 && - hdr[7] == 0x20 && - hdr[20] == 0x6A && - hdr[21] == 0x70 && - hdr[22] == 0x32) - // JP2 file format - return JP2_CFMT; - else if (hdr[0] == 0x00 && - hdr[1] == 0x00 && - hdr[2] == 0x00 && - hdr[3] == 0x0C && - hdr[4] == 0x6A && - hdr[5] == 0x50 && - hdr[6] == 0x20 && - hdr[7] == 0x20 && - hdr[20] == 0x6D && - hdr[21] == 0x6A && - hdr[22] == 0x70 && - hdr[23] == 0x32) - // MJ2 file format - return MJ2_CFMT; - else if (hdr[0] == 0xFF && - hdr[1] == 0x4F) - // J2K file format - return J2K_CFMT; - else - // unknown format - return -1; - -} - -/* we have to use this to avoid GUI-noGUI threads crashing */ -void printevent(const char *msg) -{ -#ifndef __WXGTK__ - wxMutexGuiEnter(); -#endif /* __WXGTK__ */ - wxLogMessage(wxT("%s"), msg); -#ifndef __WXGTK__ - wxMutexGuiLeave(); -#endif /* __WXGTK__ */ -} - -/* sample error callback expecting a FILE* client object */ -void jpeg2000_error_callback(const char *msg, void *client_data) { - char mess[MAX_MESSAGE_LEN + 20]; - int message_len = strlen(msg); - - if (message_len > MAX_MESSAGE_LEN) - message_len = MAX_MESSAGE_LEN; - - if (msg[message_len - 1] == '\n') - message_len--; - - sprintf(mess, "[ERROR] %.*s", message_len, msg); - printevent(mess); -} - -/* sample warning callback expecting a FILE* client object */ -void jpeg2000_warning_callback(const char *msg, void *client_data) { - char mess[MAX_MESSAGE_LEN + 20]; - int message_len = strlen(msg); - - if (message_len > MAX_MESSAGE_LEN) - message_len = MAX_MESSAGE_LEN; - - if (msg[message_len - 1] == '\n') - message_len--; - - sprintf(mess, "[WARNING] %.*s", message_len, msg); - printevent(mess); -} - -/* sample debug callback expecting no client object */ -void jpeg2000_info_callback(const char *msg, void *client_data) { - char mess[MAX_MESSAGE_LEN + 20]; - int message_len = strlen(msg); - - if (message_len > MAX_MESSAGE_LEN) - message_len = MAX_MESSAGE_LEN; - - if (msg[message_len - 1] == '\n') - message_len--; - - sprintf(mess, "[INFO] %.*s", message_len, msg); - printevent(mess); -} - -/* macro functions */ -/* From little endian to big endian, 2 and 4 bytes */ -#define BYTE_SWAP2(X) ((X & 0x00FF) << 8) | ((X & 0xFF00) >> 8) -#define BYTE_SWAP4(X) ((X & 0x000000FF) << 24) | ((X & 0x0000FF00) << 8) | ((X & 0x00FF0000) >> 8) | ((X & 0xFF000000) >> 24) - -#ifdef __WXGTK__ -#define BYTE_SWAP8(X) ((X & 0x00000000000000FFULL) << 56) | ((X & 0x000000000000FF00ULL) << 40) | \ - ((X & 0x0000000000FF0000ULL) << 24) | ((X & 0x00000000FF000000ULL) << 8) | \ - ((X & 0x000000FF00000000ULL) >> 8) | ((X & 0x0000FF0000000000ULL) >> 24) | \ - ((X & 0x00FF000000000000ULL) >> 40) | ((X & 0xFF00000000000000ULL) >> 56) -#else -#define BYTE_SWAP8(X) ((X & 0x00000000000000FF) << 56) | ((X & 0x000000000000FF00) << 40) | \ - ((X & 0x0000000000FF0000) << 24) | ((X & 0x00000000FF000000) << 8) | \ - ((X & 0x000000FF00000000) >> 8) | ((X & 0x0000FF0000000000) >> 24) | \ - ((X & 0x00FF000000000000) >> 40) | ((X & 0xFF00000000000000) >> 56) -#endif - -/* From codestream to int values */ -#define STREAM_TO_UINT32(C, P) (((unsigned long int) (C)[(P) + 0] << 24) + \ - ((unsigned long int) (C)[(P) + 1] << 16) + \ - ((unsigned long int) (C)[(P) + 2] << 8) + \ - ((unsigned long int) (C)[(P) + 3] << 0)) - -#define STREAM_TO_UINT16(C, P) (((unsigned long int) (C)[(P) + 0] << 8) + \ - ((unsigned long int) (C)[(P) + 1] << 0)) - -/* defines */ -#define SHORT_DESCR_LEN 32 -#define LONG_DESCR_LEN 256 - -/* enumeration for file formats */ -#define JPEG2000FILENUM 4 -typedef enum { - - JP2_FILE, - J2K_FILE, - MJ2_FILE, - UNK_FILE - -} jpeg2000filetype; - -/* enumeration for the box types */ -#define JPEG2000BOXNUM 23 -typedef enum { - - FILE_BOX, - JP_BOX, - FTYP_BOX, - JP2H_BOX, - IHDR_BOX, - COLR_BOX, - JP2C_BOX, - JP2I_BOX, - XML_BOX, - UUID_BOX, - UINF_BOX, - MOOV_BOX, - MVHD_BOX, - TRAK_BOX, - TKHD_BOX, - MDIA_BOX, - MINF_BOX, - STBL_BOX, - STSD_BOX, - MJP2_BOX, - MDAT_BOX, - ANY_BOX, - UNK_BOX - -} jpeg2000boxtype; - -/* jpeg2000 family box signatures */ -#define FILE_SIGN "" -#define JP_SIGN "jP\040\040" -#define FTYP_SIGN "ftyp" -#define JP2H_SIGN "jp2h" -#define IHDR_SIGN "ihdr" -#define COLR_SIGN "colr" -#define JP2C_SIGN "jp2c" -#define JP2I_SIGN "jp2i" -#define XML_SIGN "xml\040" -#define UUID_SIGN "uuid" -#define UINF_SIGN "uinf" -#define MOOV_SIGN "moov" -#define MVHD_SIGN "mvhd" -#define TRAK_SIGN "trak" -#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" -#define MDAT_SIGN "mdat" -#define ANY_SIGN "" -#define UNK_SIGN "" - -/* the box structure itself */ -struct jpeg2000boxdef { - - char value[5]; /* hexadecimal value/string*/ - char name[SHORT_DESCR_LEN]; /* short description */ - char descr[LONG_DESCR_LEN]; /* long description */ - int sbox; /* is it a superbox? */ - int req[JPEG2000FILENUM]; /* mandatory box */ - jpeg2000boxtype ins; /* contained in box... */ - -}; - -/* the possible boxes */ -struct jpeg2000boxdef jpeg2000box[] = -{ -/* sign */ {FILE_SIGN, -/* short */ "placeholder for nothing", -/* long */ "Nothing to say", -/* sbox */ 0, -/* req */ {1, 1, 1}, -/* ins */ FILE_BOX}, - -/* sign */ {JP_SIGN, -/* short */ "JPEG 2000 Signature box", -/* long */ "This box uniquely identifies the file as being part of the JPEG 2000 family of files", -/* sbox */ 0, -/* req */ {1, 1, 1}, -/* ins */ FILE_BOX}, - -/* sign */ {FTYP_SIGN, -/* short */ "File Type box", -/* long */ "This box specifies file type, version and compatibility information, including specifying if this file " - "is a conforming JP2 file or if it can be read by a conforming JP2 reader", -/* sbox */ 0, -/* req */ {1, 1, 1}, -/* ins */ FILE_BOX}, - -/* sign */ {JP2H_SIGN, -/* short */ "JP2 Header box", -/* long */ "This box contains a series of boxes that contain header-type information about the file", -/* sbox */ 1, -/* req */ {1, 1, 1}, -/* ins */ FILE_BOX}, - -/* sign */ {IHDR_SIGN, -/* short */ "Image Header box", -/* long */ "This box specifies the size of the image and other related fields", -/* sbox */ 0, -/* req */ {1, 1, 1}, -/* ins */ JP2H_BOX}, - -/* sign */ {COLR_SIGN, -/* short */ "Colour Specification box", -/* long */ "This box specifies the colourspace of the image", -/* sbox */ 0, -/* req */ {1, 1, 1}, -/* ins */ JP2H_BOX}, - -/* sign */ {JP2C_SIGN, -/* short */ "Contiguous Codestream box", -/* long */ "This box contains the codestream as defined by Annex A", -/* sbox */ 0, -/* req */ {1, 1, 1}, -/* ins */ FILE_BOX}, - -/* sign */ {JP2I_SIGN, -/* short */ "Intellectual Property box", -/* long */ "This box contains intellectual property information about the image", -/* sbox */ 0, -/* req */ {0, 0, 0}, -/* ins */ FILE_BOX}, - -/* sign */ {XML_SIGN, -/* short */ "XML box", -/* long */ "This box provides a tool by which vendors can add XML formatted information to a JP2 file", -/* sbox */ 0, -/* req */ {0, 0, 0}, -/* ins */ FILE_BOX}, - -/* sign */ {UUID_SIGN, -/* short */ "UUID box", -/* long */ "This box provides a tool by which vendors can add additional information to a file " - "without risking conflict with other vendors", -/* sbox */ 0, -/* req */ {0, 0, 0}, -/* ins */ FILE_BOX}, - -/* sign */ {UINF_SIGN, -/* short */ "UUID Info box", -/* long */ "This box provides a tool by which a vendor may provide access to additional information associated with a UUID", -/* sbox */ 0, -/* req */ {0, 0, 0}, -/* ins */ FILE_BOX}, - -/* sign */ {MOOV_SIGN, -/* short */ "Movie box", -/* long */ "This box contains the media data. In video tracks, this box would contain JPEG2000 video frames", -/* sbox */ 1, -/* req */ {1, 1, 1}, -/* ins */ FILE_BOX}, - -/* sign */ {MVHD_SIGN, -/* short */ "Movie Header box", -/* long */ "This box defines overall information which is media-independent, and relevant to the entire presentation " - "considered as a whole", -/* sbox */ 0, -/* req */ {1, 1, 1}, -/* ins */ MOOV_BOX}, - -/* sign */ {TRAK_SIGN, -/* short */ "Track box", -/* long */ "This is a container box for a single track of a presentation. A presentation may consist of one or more tracks", -/* sbox */ 1, -/* req */ {1, 1, 1}, -/* ins */ MOOV_BOX}, - -/* sign */ {TKHD_SIGN, -/* short */ "Track Header box", -/* long */ "This box specifies the characteristics of a single track. Exactly one Track Header Box is contained in a track", -/* sbox */ 0, -/* req */ {1, 1, 1}, -/* ins */ TRAK_BOX}, - -/* sign */ {MDIA_SIGN, -/* short */ "Media box", -/* long */ "The media declaration container contains all the objects which declare information about the media data " - "within a track", -/* sbox */ 1, -/* req */ {1, 1, 1}, -/* ins */ TRAK_BOX}, - -/* sign */ {MINF_SIGN, -/* short */ "Media Information box", -/* long */ "This box contains all the objects which declare characteristic information of the media in the track", -/* sbox */ 1, -/* req */ {1, 1, 1}, -/* ins */ MDIA_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", -/* sbox */ 1, -/* req */ {1, 1, 1}, -/* ins */ MINF_BOX}, - -/* sign */ {STSD_SIGN, -/* short */ "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 */ {MJP2_SIGN, -/* short */ "MJP2 Sample Description box", -/* long */ "The MJP2 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 */ {MDAT_SIGN, -/* short */ "Media Data box", -/* long */ "The meta-data for a presentation is stored in the single Movie Box which occurs at the top-level of a file", -/* sbox */ 1, -/* req */ {1, 1, 1}, -/* ins */ FILE_BOX}, - -/* sign */ {ANY_SIGN, -/* short */ "Any box", -/* long */ "All the existing boxes", -/* sbox */ 0, -/* req */ {0, 0, 0}, -/* ins */ FILE_BOX}, - -/* sign */ {UNK_SIGN, -/* short */ "Unknown Type box", -/* long */ "The signature is not recognised to be that of an existing box", -/* sbox */ 0, -/* req */ {0, 0, 0}, -/* ins */ ANY_BOX} - -}; - -/* declaration */ -int -jpeg2000_box_handler_function(jpeg2000boxtype boxtype, wxInputStream& stream, unsigned long int filepoint, - unsigned long int filelimit, int level, char *scansign, - unsigned long int *scanpoint); - -#ifdef __WXMSW__ -typedef unsigned __int64 int8byte; -#endif // __WXMSW__ - -#ifdef __WXGTK__ -typedef unsigned long long int8byte; -#endif // __WXGTK__ - -/* internal mini-search for a box signature */ -int -jpeg2000_file_parse(wxInputStream& stream, unsigned long int filepoint, unsigned long int filelimit, int level, - char *scansign, unsigned long int *scanpoint) -{ - unsigned long int LBox = 0x00000000; - char TBox[5] = "\0\0\0\0"; - int8byte XLBox = 0x0000000000000000; - unsigned long int box_length = 0; - int last_box = 0, box_num = 0; - int box_type = ANY_BOX; - unsigned char fourbytes[4]; - int box_number = 0; - - /* cycle all over the file */ - box_num = 0; - last_box = 0; - while (!last_box) { - - /* do not exceed file limit */ - if (filepoint >= filelimit) - return (0); - - /* seek on file */ - if (stream.SeekI(filepoint, wxFromStart) == wxInvalidOffset) - return (-1); - - /* read the mandatory LBox, 4 bytes */ - if (!stream.Read(fourbytes, 4)) { - wxLogError(wxT("Problem reading LBox from the file (file ended?)")); - return -1; - }; - LBox = STREAM_TO_UINT32(fourbytes, 0); - - /* read the mandatory TBox, 4 bytes */ - if (!stream.Read(TBox, 4)) { - wxLogError(wxT("Problem reading TBox from the file (file ended?)")); - return -1; - }; - - /* look if scansign is got */ - if ((scansign != NULL) && (memcmp(TBox, scansign, 4) == 0)) { - /* hack/exploit */ - // stop as soon as you find the level-th codebox - if (box_number == level) { - memcpy(scansign, " ", 4); - *scanpoint = filepoint; - return (0); - } else - box_number++; - - }; - - /* determine the box type */ - for (box_type = JP_BOX; box_type < UNK_BOX; box_type++) - if (memcmp(TBox, jpeg2000box[box_type].value, 4) == 0) - break; - - /* read the optional XLBox, 8 bytes */ - if (LBox == 1) { - - if (!stream.Read(&XLBox, 8)) { - wxLogError(wxT("Problem reading XLBox from the file (file ended?)")); - return -1; - }; - box_length = (unsigned long int) BYTE_SWAP8(XLBox); - - } else if (LBox == 0x00000000) { - - /* last box in file */ - last_box = 1; - box_length = filelimit - filepoint; - - } else - - box_length = LBox; - - - /* go deep in the box */ - jpeg2000_box_handler_function((jpeg2000boxtype) box_type, - stream, (LBox == 1) ? (filepoint + 16) : (filepoint + 8), - filepoint + box_length, level, scansign, scanpoint); - - /* if it's a superbox go inside it */ - if (jpeg2000box[box_type].sbox) - jpeg2000_file_parse(stream, (LBox == 1) ? (filepoint + 16) : (filepoint + 8), filepoint + box_length, - level, scansign, scanpoint); - - /* increment box number and filepoint*/ - box_num++; - filepoint += box_length; - - }; - - /* all good */ - return (0); -} - -// search first contiguos codestream box in an mj2 file -unsigned long int -searchjpeg2000c(wxInputStream& stream, unsigned long int fsize, int number) -{ - char scansign[] = "jp2c"; - unsigned long int scanpoint = 0L; - - wxLogMessage(wxT("Searching jp2c box... ")); - - /* do the parsing */ - if (jpeg2000_file_parse(stream, 0, fsize, number, scansign, &scanpoint) < 0) - wxLogMessage(wxT("Unrecoverable error during JPEG 2000 box parsing: stopping")); - - if (strcmp(scansign, " ")) - wxLogMessage(wxT("Box not found")); - else { - - wxLogMessage(wxString::Format(wxT("Box found at byte %d"), scanpoint)); - - }; - - return (scanpoint); -} - -// search the jp2h box in the file -unsigned long int -searchjpeg2000headerbox(wxInputStream& stream, unsigned long int fsize) -{ - char scansign[] = "jp2h"; - unsigned long int scanpoint = 0L; - - wxLogMessage(wxT("Searching jp2h box... ")); - - /* do the parsing */ - if (jpeg2000_file_parse(stream, 0, fsize, 0, scansign, &scanpoint) < 0) - wxLogMessage(wxT("Unrecoverable error during JPEG 2000 box parsing: stopping")); - - if (strcmp(scansign, " ")) - wxLogMessage(wxT("Box not found")); - else - wxLogMessage(wxString::Format(wxT("Box found at byte %d"), scanpoint)); - - return (scanpoint); -} - -/* handling functions */ -#define ITEM_PER_ROW 10 - -/* Box handler function */ -int -jpeg2000_box_handler_function(jpeg2000boxtype boxtype, wxInputStream& stream, unsigned long int filepoint, - unsigned long int filelimit, int level, - char *scansign, unsigned long int *scanpoint) -{ - switch (boxtype) { - - /* Sample Description box */ - case (STSD_BOX): - jpeg2000_file_parse(stream, filepoint + 8, filelimit, level, scansign, scanpoint); - break; - - /* MJP2 Sample Description box */ - case (MJP2_BOX): - jpeg2000_file_parse(stream, filepoint + 78, filelimit, level, scansign, scanpoint); - break; - - /* not yet implemented */ - default: - break; - - }; - - return (0); -} - -// the jP and ftyp parts of the header -#define jpeg2000headSIZE 32 -unsigned char jpeg2000head[jpeg2000headSIZE] = { - 0x00, 0x00, 0x00, 0x0C, 'j', 'P', ' ', ' ', - 0x0D, 0x0A, 0x87, 0x0A, 0x00, 0x00, 0x00, 0x14, - 'f', 't', 'y', 'p', 'j', 'p', '2', ' ', - 0x00, 0x00, 0x00, 0x00, 'j', 'p', '2', ' ' -}; - -///////////////////////////////////////////////// -///////////////////////////////////////////////// - -// load the jpeg2000 file format -bool wxJPEG2000Handler::LoadFile(wxImage *image, wxInputStream& stream, bool verbose, int index) -{ - opj_dparameters_t parameters; /* decompression parameters */ - opj_event_mgr_t event_mgr; /* event manager */ - opj_image_t *opjimage = NULL; - unsigned char *src = NULL; - unsigned char *ptr; - int file_length, jp2c_point, jp2h_point; - unsigned long int jp2hboxlen, jp2cboxlen; - opj_codestream_info_t cstr_info; /* Codestream information structure */ - unsigned char hdr[24]; - int jpfamform; - - // destroy the image - image->Destroy(); - - /* read the beginning of the file to check the type */ - if (!stream.Read(hdr, WXSIZEOF(hdr))) - return false; - if ((jpfamform = jpeg2000familytype(hdr, WXSIZEOF(hdr))) < 0) - return false; - stream.SeekI(0, wxFromStart); - - /* handle to a decompressor */ - opj_dinfo_t* dinfo = NULL; - opj_cio_t *cio = NULL; - - /* configure the event callbacks */ - memset(&event_mgr, 0, sizeof(opj_event_mgr_t)); - event_mgr.error_handler = jpeg2000_error_callback; - event_mgr.warning_handler = jpeg2000_warning_callback; - event_mgr.info_handler = jpeg2000_info_callback; - - /* set decoding parameters to default values */ - opj_set_default_decoder_parameters(¶meters); - - /* prepare parameters */ - strncpy(parameters.infile, "", sizeof(parameters.infile) - 1); - strncpy(parameters.outfile, "", sizeof(parameters.outfile) - 1); - parameters.decod_format = jpfamform; - 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 */ - if (jpfamform == JP2_CFMT || jpfamform == MJ2_CFMT) - dinfo = opj_create_decompress(CODEC_JP2); - else if (jpfamform == J2K_CFMT) - dinfo = opj_create_decompress(CODEC_J2K); - else - return false; - - /* find length of the stream */ - stream.SeekI(0, wxFromEnd); - file_length = (int) stream.TellI(); - - /* it's a movie */ - if (jpfamform == MJ2_CFMT) { - /* search for the first codestream box and the movie header box */ - jp2c_point = searchjpeg2000c(stream, file_length, m_framenum); - jp2h_point = searchjpeg2000headerbox(stream, file_length); - - // read the jp2h box and store it - stream.SeekI(jp2h_point, wxFromStart); - stream.Read(&jp2hboxlen, sizeof(unsigned long int)); - jp2hboxlen = BYTE_SWAP4(jp2hboxlen); - - // read the jp2c box and store it - stream.SeekI(jp2c_point, wxFromStart); - stream.Read(&jp2cboxlen, sizeof(unsigned long int)); - jp2cboxlen = BYTE_SWAP4(jp2cboxlen); - - // malloc memory source - src = (unsigned char *) malloc(jpeg2000headSIZE + jp2hboxlen + jp2cboxlen); - - // copy the jP and ftyp - memcpy(src, jpeg2000head, jpeg2000headSIZE); - - // copy the jp2h - stream.SeekI(jp2h_point, wxFromStart); - stream.Read(&src[jpeg2000headSIZE], jp2hboxlen); - - // copy the jp2c - stream.SeekI(jp2c_point, wxFromStart); - stream.Read(&src[jpeg2000headSIZE + jp2hboxlen], jp2cboxlen); - } else if (jpfamform == JP2_CFMT || jpfamform == J2K_CFMT) { - /* It's a plain image */ - /* get data */ - stream.SeekI(0, wxFromStart); - src = (unsigned char *) malloc(file_length); - stream.Read(src, file_length); - } else - return false; - - /* catch events using our callbacks and give a local context */ - opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, stderr); - - /* setup the decoder decoding parameters using user parameters */ - opj_setup_decoder(dinfo, ¶meters); - - /* open a byte stream */ - if (jpfamform == MJ2_CFMT) - cio = opj_cio_open((opj_common_ptr)dinfo, src, jpeg2000headSIZE + jp2hboxlen + jp2cboxlen); - else if (jpfamform == JP2_CFMT || jpfamform == J2K_CFMT) - cio = opj_cio_open((opj_common_ptr)dinfo, src, file_length); - else { - free(src); - return false; - } - - /* decode the stream and fill the image structure */ - opjimage = opj_decode_with_info(dinfo, cio, &cstr_info); - if (!opjimage) { - wxMutexGuiEnter(); - wxLogError(wxT("JPEG 2000 failed to decode image!")); - wxMutexGuiLeave(); - opj_destroy_decompress(dinfo); - opj_cio_close(cio); - free(src); - return false; - } - - /* close the byte stream */ - opj_cio_close(cio); - - /* - - - At this point, we have the structure "opjimage" that is filled with decompressed - data, as processed by the OpenJPEG decompression engine - - - We need to fill the class "image" with the proper pixel sample values - - */ - { - int shiftbpp; - int c, tempcomps; - - // check components number - if (m_components > opjimage->numcomps) - m_components = opjimage->numcomps; - - // check image depth (only on the first one, for now) - if (m_components) - shiftbpp = opjimage->comps[m_components - 1].prec - 8; - else - shiftbpp = opjimage->comps[0].prec - 8; - - // prepare image size - if (m_components) - image->Create(opjimage->comps[m_components - 1].w, opjimage->comps[m_components - 1].h, true); - else - image->Create(opjimage->comps[0].w, opjimage->comps[0].h, true); - - // access image raw data - image->SetMask(false); - ptr = image->GetData(); - - // workaround for components different from 1 or 3 - if ((opjimage->numcomps != 1) && (opjimage->numcomps != 3)) { -#ifndef __WXGTK__ - wxMutexGuiEnter(); -#endif /* __WXGTK__ */ - wxLogMessage(wxT("JPEG2000: weird number of components")); -#ifndef __WXGTK__ - wxMutexGuiLeave(); -#endif /* __WXGTK__ */ - tempcomps = 1; - } else - tempcomps = opjimage->numcomps; - - // workaround for subsampled components - for (c = 1; c < tempcomps; c++) { - if ((opjimage->comps[c].w != opjimage->comps[c - 1].w) || (opjimage->comps[c].h != opjimage->comps[c - 1].h)) { - tempcomps = 1; - break; - } - } - - // workaround for different precision components - for (c = 1; c < tempcomps; c++) { - if (opjimage->comps[c].bpp != opjimage->comps[c - 1].bpp) { - tempcomps = 1; - break; - } - } - - // only one component selected - if (m_components) - tempcomps = 1; - - // RGB color picture - if (tempcomps == 3) { - int row, col; - int *r = opjimage->comps[0].data; - int *g = opjimage->comps[1].data; - int *b = opjimage->comps[2].data; - if (shiftbpp > 0) { - for (row = 0; row < opjimage->comps[0].h; row++) { - for (col = 0; col < opjimage->comps[0].w; col++) { - - *(ptr++) = (*(r++)) >> shiftbpp; - *(ptr++) = (*(g++)) >> shiftbpp; - *(ptr++) = (*(b++)) >> shiftbpp; - - } - } - - } else if (shiftbpp < 0) { - for (row = 0; row < opjimage->comps[0].h; row++) { - for (col = 0; col < opjimage->comps[0].w; col++) { - - *(ptr++) = (*(r++)) << -shiftbpp; - *(ptr++) = (*(g++)) << -shiftbpp; - *(ptr++) = (*(b++)) << -shiftbpp; - - } - } - - } else { - for (row = 0; row < opjimage->comps[0].h; row++) { - for (col = 0; col < opjimage->comps[0].w; col++) { - - *(ptr++) = *(r++); - *(ptr++) = *(g++); - *(ptr++) = *(b++); - - } - } - } - } - - // B/W picture - if (tempcomps == 1) { - int row, col; - int selcomp; - - if (m_components) - selcomp = m_components - 1; - else - selcomp = 0; - - int *y = opjimage->comps[selcomp].data; - if (shiftbpp > 0) { - for (row = 0; row < opjimage->comps[selcomp].h; row++) { - for (col = 0; col < opjimage->comps[selcomp].w; col++) { - - *(ptr++) = (*(y)) >> shiftbpp; - *(ptr++) = (*(y)) >> shiftbpp; - *(ptr++) = (*(y++)) >> shiftbpp; - - } - } - } else if (shiftbpp < 0) { - for (row = 0; row < opjimage->comps[selcomp].h; row++) { - for (col = 0; col < opjimage->comps[selcomp].w; col++) { - - *(ptr++) = (*(y)) << -shiftbpp; - *(ptr++) = (*(y)) << -shiftbpp; - *(ptr++) = (*(y++)) << -shiftbpp; - - } - } - } else { - for (row = 0; row < opjimage->comps[selcomp].h; row++) { - for (col = 0; col < opjimage->comps[selcomp].w; col++) { - - *(ptr++) = *(y); - *(ptr++) = *(y); - *(ptr++) = *(y++); - - } - } - } - } - - - } - - wxMutexGuiEnter(); - wxLogMessage(wxT("JPEG 2000 image loaded.")); - wxMutexGuiLeave(); - - /* close openjpeg structs */ - opj_destroy_decompress(dinfo); - opj_image_destroy(opjimage); - free(src); - - if (!image->Ok()) - return false; - else - return true; - -} - -#define CINEMA_24_CS 1302083 /* Codestream length for 24fps */ -#define CINEMA_48_CS 651041 /* Codestream length for 48fps */ -#define COMP_24_CS 1041666 /* Maximum size per color component for 2K & 4K @ 24fps */ -#define COMP_48_CS 520833 /* Maximum size per color component for 2K @ 48fps */ - -// save the j2k codestream -bool wxJPEG2000Handler::SaveFile( wxImage *wimage, wxOutputStream& stream, bool verbose ) -{ - opj_cparameters_t parameters; /* compression parameters */ - opj_event_mgr_t event_mgr; /* event manager */ - opj_image_t *oimage = NULL; - opj_image_cmptparm_t *cmptparm; - opj_cio_t *cio = NULL; - opj_codestream_info_t cstr_info; - int codestream_length; - bool bSuccess; - int i; - char indexfilename[OPJ_PATH_LEN] = ""; /* index file name */ - - /* - configure the event callbacks (not required) - setting of each callback is optionnal - */ - memset(&event_mgr, 0, sizeof(opj_event_mgr_t)); - event_mgr.error_handler = jpeg2000_error_callback; - event_mgr.warning_handler = jpeg2000_warning_callback; - event_mgr.info_handler = jpeg2000_info_callback; - - /* set encoding parameters to default values */ - opj_set_default_encoder_parameters(¶meters); - - /* load parameters */ - parameters.cp_cinema = OFF; - - /* subsampling */ - if (sscanf(m_subsampling.ToAscii(), "%d,%d", &(parameters.subsampling_dx), &(parameters.subsampling_dy)) != 2) { - wxLogError(wxT("Wrong sub-sampling encoder setting: dx,dy")); - return false; - } - - /* compression rates */ - if ((m_rates != wxT("")) && (!m_enablequality)) { - const char *s1 = m_rates.ToAscii(); - wxLogMessage(wxT("rates %s"), s1); - while (sscanf(s1, "%f", &(parameters.tcp_rates[parameters.tcp_numlayers])) == 1) { - parameters.tcp_numlayers++; - while (*s1 && *s1 != ',') { - s1++; - } - if (!*s1) - break; - s1++; - } - wxLogMessage(wxT("%d layers"), parameters.tcp_numlayers); - parameters.cp_disto_alloc = 1; - } - - /* image quality, dB */ - if ((m_quality != wxT("")) && (m_enablequality)) { - const char *s2 = m_quality.ToAscii(); - wxLogMessage(wxT("qualities %s"), s2); - while (sscanf(s2, "%f", ¶meters.tcp_distoratio[parameters.tcp_numlayers]) == 1) { - parameters.tcp_numlayers++; - while (*s2 && *s2 != ',') { - s2++; - } - if (!*s2) - break; - s2++; - } - wxLogMessage(wxT("%d layers"), parameters.tcp_numlayers); - parameters.cp_fixed_quality = 1; - } - - /* image origin */ - if (sscanf(m_origin.ToAscii(), "%d,%d", ¶meters.image_offset_x0, ¶meters.image_offset_y0) != 2) { - wxLogError(wxT("bad coordinate of the image origin: x0,y0")); - return false; - } - - /* Create comment for codestream */ - if(m_enablecomm) { - parameters.cp_comment = (char *) malloc(strlen(m_comment.ToAscii()) + 1); - if(parameters.cp_comment) { - strcpy(parameters.cp_comment, m_comment.ToAscii()); - } - } else { - parameters.cp_comment = NULL; - } - - /* indexing file */ - if (m_enableidx) { - strncpy(indexfilename, m_index.ToAscii(), OPJ_PATH_LEN); - wxLogMessage(wxT("index file is %s"), indexfilename); - } - - /* if no rate entered, lossless by default */ - if (parameters.tcp_numlayers == 0) { - parameters.tcp_rates[0] = 0; /* MOD antonin : losslessbug */ - parameters.tcp_numlayers++; - parameters.cp_disto_alloc = 1; - } - - /* irreversible transform */ - parameters.irreversible = (m_irreversible == true) ? 1 : 0; - - /* resolutions */ - parameters.numresolution = m_resolutions; - - /* codeblocks size */ - if (m_cbsize != wxT("")) { - int cblockw_init = 0, cblockh_init = 0; - sscanf(m_cbsize.ToAscii(), "%d,%d", &cblockw_init, &cblockh_init); - if (cblockw_init * cblockh_init > 4096 || cblockw_init > 1024 || cblockw_init < 4 || cblockh_init > 1024 || cblockh_init < 4) { - wxLogError(wxT("!! Size of code_block error !! Restrictions:\n width*height<=4096\n 4<=width,height<= 1024")); - return false; - } - parameters.cblockw_init = cblockw_init; - parameters.cblockh_init = cblockh_init; - } - - /* precincts size */ - if (m_prsize != wxT("")) { - char sep; - int res_spec = 0; - char *s = (char *) m_prsize.c_str(); - do { - sep = 0; - sscanf(s, "[%d,%d]%c", ¶meters.prcw_init[res_spec], ¶meters.prch_init[res_spec], &sep); - parameters.csty |= 0x01; - res_spec++; - s = strpbrk(s, "]") + 2; - } while (sep == ','); - parameters.res_spec = res_spec; - } - - /* tiles */ - if (m_tsize != wxT("")) { - sscanf(m_tsize.ToAscii(), "%d,%d", ¶meters.cp_tdx, ¶meters.cp_tdy); - parameters.tile_size_on = true; - } - - /* tile origin */ - if (sscanf(m_torigin.ToAscii(), "%d,%d", ¶meters.cp_tx0, ¶meters.cp_ty0) != 2) { - wxLogError(wxT("tile offset setting error: X0,Y0")); - return false; - } - - /* use SOP */ - if (m_enablesop) - parameters.csty |= 0x02; - - /* use EPH */ - if (m_enableeph) - parameters.csty |= 0x04; - - /* multiple component transform */ - if (m_multicomp) - parameters.tcp_mct = 1; - else - parameters.tcp_mct = 0; - - /* mode switch */ - parameters.mode = (m_enablebypass ? 1 : 0) + (m_enablereset ? 2 : 0) - + (m_enablerestart ? 4 : 0) + (m_enablevsc ? 8 : 0) - + (m_enableerterm ? 16 : 0) + (m_enablesegmark ? 32 : 0); - - /* progression order */ - switch (m_progression) { - - /* LRCP */ - case 0: - parameters.prog_order = LRCP; - break; - - /* RLCP */ - case 1: - parameters.prog_order = RLCP; - break; - - /* RPCL */ - case 2: - parameters.prog_order = RPCL; - break; - - /* PCRL */ - case 3: - parameters.prog_order = PCRL; - break; - - /* CPRL */ - case 4: - parameters.prog_order = CPRL; - break; - - /* DCI2K24 */ - case 5: - parameters.cp_cinema = CINEMA2K_24; - parameters.cp_rsiz = CINEMA2K; - break; - - /* DCI2K48 */ - case 6: - parameters.cp_cinema = CINEMA2K_48; - parameters.cp_rsiz = CINEMA2K; - break; - - /* DCI4K */ - case 7: - parameters.cp_cinema = CINEMA4K_24; - parameters.cp_rsiz = CINEMA4K; - break; - - default: - break; - } - - /* check cinema */ - if (parameters.cp_cinema) { - - /* set up */ - parameters.tile_size_on = false; - parameters.cp_tdx=1; - parameters.cp_tdy=1; - - /*Tile part*/ - parameters.tp_flag = 'C'; - parameters.tp_on = 1; - - /*Tile and Image shall be at (0,0)*/ - parameters.cp_tx0 = 0; - parameters.cp_ty0 = 0; - parameters.image_offset_x0 = 0; - parameters.image_offset_y0 = 0; - - /*Codeblock size= 32*32*/ - parameters.cblockw_init = 32; - parameters.cblockh_init = 32; - parameters.csty |= 0x01; - - /*The progression order shall be CPRL*/ - parameters.prog_order = CPRL; - - /* No ROI */ - parameters.roi_compno = -1; - - parameters.subsampling_dx = 1; - parameters.subsampling_dy = 1; - - /* 9-7 transform */ - parameters.irreversible = 1; - - } - - /* convert wx image into opj image */ - cmptparm = (opj_image_cmptparm_t*) malloc(3 * sizeof(opj_image_cmptparm_t)); - - /* initialize opj image components */ - memset(&cmptparm[0], 0, 3 * sizeof(opj_image_cmptparm_t)); - for(i = 0; i < 3; i++) { - cmptparm[i].prec = 8; - cmptparm[i].bpp = 8; - cmptparm[i].sgnd = false; - cmptparm[i].dx = parameters.subsampling_dx; - cmptparm[i].dy = parameters.subsampling_dy; - cmptparm[i].w = wimage->GetWidth(); - cmptparm[i].h = wimage->GetHeight(); - } - - /* create the image */ - oimage = opj_image_create(3, &cmptparm[0], CLRSPC_SRGB); - if(!oimage) { - if (cmptparm) - free(cmptparm); - return false; - } - - /* set image offset and reference grid */ - oimage->x0 = parameters.image_offset_x0; - oimage->y0 = parameters.image_offset_y0; - oimage->x1 = parameters.image_offset_x0 + (wimage->GetWidth() - 1) * 1 + 1; - oimage->y1 = parameters.image_offset_y0 + (wimage->GetHeight() - 1) * 1 + 1; - - /* load image data */ - unsigned char *value = wimage->GetData(); - int area = wimage->GetWidth() * wimage->GetHeight(); - for (i = 0; i < area; i++) { - oimage->comps[0].data[i] = *(value++); - oimage->comps[1].data[i] = *(value++); - oimage->comps[2].data[i] = *(value++); - } - - /* check cinema again */ - if (parameters.cp_cinema) { - int i; - float temp_rate; - opj_poc_t *POC = NULL; - - switch (parameters.cp_cinema) { - - case CINEMA2K_24: - case CINEMA2K_48: - if (parameters.numresolution > 6) { - parameters.numresolution = 6; - } - if (!((oimage->comps[0].w == 2048) | (oimage->comps[0].h == 1080))) { - wxLogWarning(wxT("Image coordinates %d x %d is not 2K compliant. JPEG Digital Cinema Profile-3 " - "(2K profile) compliance requires that at least one of coordinates match 2048 x 1080"), - oimage->comps[0].w, oimage->comps[0].h); - parameters.cp_rsiz = STD_RSIZ; - } - break; - - case CINEMA4K_24: - if (parameters.numresolution < 1) { - parameters.numresolution = 1; - } else if (parameters.numresolution > 7) { - parameters.numresolution = 7; - } - if (!((oimage->comps[0].w == 4096) | (oimage->comps[0].h == 2160))) { - wxLogWarning(wxT("Image coordinates %d x %d is not 4K compliant. JPEG Digital Cinema Profile-4" - "(4K profile) compliance requires that at least one of coordinates match 4096 x 2160"), - oimage->comps[0].w, oimage->comps[0].h); - parameters.cp_rsiz = STD_RSIZ; - } - parameters.POC[0].tile = 1; - parameters.POC[0].resno0 = 0; - parameters.POC[0].compno0 = 0; - parameters.POC[0].layno1 = 1; - parameters.POC[0].resno1 = parameters.numresolution - 1; - parameters.POC[0].compno1 = 3; - parameters.POC[0].prg1 = CPRL; - parameters.POC[1].tile = 1; - parameters.POC[1].resno0 = parameters.numresolution - 1; - parameters.POC[1].compno0 = 0; - parameters.POC[1].layno1 = 1; - parameters.POC[1].resno1 = parameters.numresolution; - parameters.POC[1].compno1 = 3; - parameters.POC[1].prg1 = CPRL; - parameters.numpocs = 2; - break; - } - - switch (parameters.cp_cinema) { - case CINEMA2K_24: - case CINEMA4K_24: - for (i = 0 ; i < parameters.tcp_numlayers; i++) { - temp_rate = 0; - if (parameters.tcp_rates[i] == 0) { - parameters.tcp_rates[0] = ((float) (oimage->numcomps * oimage->comps[0].w * oimage->comps[0].h * oimage->comps[0].prec)) / - (CINEMA_24_CS * 8 * oimage->comps[0].dx * oimage->comps[0].dy); - }else{ - temp_rate = ((float) (oimage->numcomps * oimage->comps[0].w * oimage->comps[0].h * oimage->comps[0].prec)) / - (parameters.tcp_rates[i] * 8 * oimage->comps[0].dx * oimage->comps[0].dy); - if (temp_rate > CINEMA_24_CS ) { - parameters.tcp_rates[i]= ((float) (oimage->numcomps * oimage->comps[0].w * oimage->comps[0].h * oimage->comps[0].prec)) / - (CINEMA_24_CS * 8 * oimage->comps[0].dx * oimage->comps[0].dy); - } else { - /* do nothing */ - } - } - } - parameters.max_comp_size = COMP_24_CS; - break; - - case CINEMA2K_48: - for (i = 0; i < parameters.tcp_numlayers; i++) { - temp_rate = 0 ; - if (parameters.tcp_rates[i] == 0) { - parameters.tcp_rates[0] = ((float) (oimage->numcomps * oimage->comps[0].w * oimage->comps[0].h * oimage->comps[0].prec)) / - (CINEMA_48_CS * 8 * oimage->comps[0].dx * oimage->comps[0].dy); - }else{ - temp_rate =((float) (oimage->numcomps * oimage->comps[0].w * oimage->comps[0].h * oimage->comps[0].prec)) / - (parameters.tcp_rates[i] * 8 * oimage->comps[0].dx * oimage->comps[0].dy); - if (temp_rate > CINEMA_48_CS ){ - parameters.tcp_rates[0]= ((float) (oimage->numcomps * oimage->comps[0].w * oimage->comps[0].h * oimage->comps[0].prec)) / - (CINEMA_48_CS * 8 * oimage->comps[0].dx * oimage->comps[0].dy); - }else{ - /* do nothing */ - } - } - } - parameters.max_comp_size = COMP_48_CS; - break; - } - - parameters.cp_disto_alloc = 1; - } - - /* get a J2K compressor handle */ - opj_cinfo_t* cinfo = opj_create_compress(CODEC_J2K); - - /* catch events using our callbacks and give a local context */ - opj_set_event_mgr((opj_common_ptr)cinfo, &event_mgr, stderr); - - /* setup the encoder parameters using the current image and user parameters */ - opj_setup_encoder(cinfo, ¶meters, oimage); - - /* open a byte stream for writing */ - /* allocate memory for all tiles */ - cio = opj_cio_open((opj_common_ptr)cinfo, NULL, 0); - - /* encode the image */ - bSuccess = opj_encode_with_info(cinfo, cio, oimage, &cstr_info); - if (!bSuccess) { - - opj_cio_close(cio); - opj_destroy_compress(cinfo); - opj_image_destroy(oimage); - if (cmptparm) - free(cmptparm); - if(parameters.cp_comment) - free(parameters.cp_comment); - if(parameters.cp_matrice) - free(parameters.cp_matrice); - -#ifndef __WXGTK__ - wxMutexGuiEnter(); -#endif /* __WXGTK__ */ - - wxLogError(wxT("failed to encode image")); - -#ifndef __WXGTK__ - wxMutexGuiLeave(); -#endif /* __WXGTK__ */ - - return false; - } - codestream_length = cio_tell(cio); - wxLogMessage(wxT("Codestream: %d bytes"), codestream_length); - - /* write the buffer to stream */ - stream.Write(cio->buffer, codestream_length); - - /* close and free the byte stream */ - opj_cio_close(cio); - - /* Write the index to disk */ - if (*indexfilename) { - if (write_index_file(&cstr_info, indexfilename)) { - wxLogError(wxT("Failed to output index file")); - } - } - - /* free remaining compression structures */ - opj_destroy_compress(cinfo); - - /* free image data */ - opj_image_destroy(oimage); - - if (cmptparm) - free(cmptparm); - if(parameters.cp_comment) - free(parameters.cp_comment); - if(parameters.cp_matrice) - free(parameters.cp_matrice); - -#ifndef __WXGTK__ - wxMutexGuiEnter(); -#endif /* __WXGTK__ */ - - wxLogMessage(wxT("J2K: Image encoded!")); - -#ifndef __WXGTK__ - wxMutexGuiLeave(); -#endif /* __WXGTK__ */ - - return true; -} - -#ifdef __VISUALC__ - #pragma warning(default:4611) -#endif /* VC++ */ - -// recognize the JPEG 2000 family starting box or the 0xFF4F JPEG 2000 SOC marker -bool wxJPEG2000Handler::DoCanRead(wxInputStream& stream) -{ - unsigned char hdr[24]; - int jpfamform; - - if ( !stream.Read(hdr, WXSIZEOF(hdr)) ) - return false; - - jpfamform = jpeg2000familytype(hdr, WXSIZEOF(hdr)); - - return ((jpfamform == JP2_CFMT) || (jpfamform == MJ2_CFMT) || (jpfamform == J2K_CFMT)); -} - -#endif // wxUSE_STREAMS - -#endif // wxUSE_LIBOPENJPEG +/* + * Copyright (c) 2007, Digital Signal Processing Laboratory, Università degli studi di Perugia (UPG), Italy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are 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. + */ +///////////////////////////////////////////////////////////////////////////// +// Name: imagjpeg2000.cpp +// Purpose: wxImage JPEG 2000 family file format handler +// Author: Giuseppe Baruffa - based on imagjpeg.cpp, Vaclav Slavik +// RCS-ID: $Id: imagjpeg2000.cpp,v 0.00 2008/01/31 10:58:00 MW Exp $ +// Copyright: (c) Giuseppe Baruffa +// Licence: wxWindows licence +///////////////////////////////////////////////////////////////////////////// + +// For compilers that support precompilation, includes "wx.h". +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ + #pragma hdrstop +#endif + +#if wxUSE_IMAGE && wxUSE_LIBOPENJPEG + +#include "imagjpeg2000.h" + +#ifndef WX_PRECOMP + #include "wx/log.h" + #include "wx/app.h" + #include "wx/intl.h" + #include "wx/bitmap.h" + #include "wx/module.h" +#endif + +#include "libopenjpeg/openjpeg.h" + +#include "wx/filefn.h" +#include "wx/wfstream.h" + +// ---------------------------------------------------------------------------- +// types +// ---------------------------------------------------------------------------- + + +//----------------------------------------------------------------------------- +// wxJPEG2000Handler +//----------------------------------------------------------------------------- + +IMPLEMENT_DYNAMIC_CLASS(wxJPEG2000Handler,wxImageHandler) + +#if wxUSE_STREAMS + +//------------- JPEG 2000 Data Source Manager + +#define J2K_CFMT 0 +#define JP2_CFMT 1 +#define JPT_CFMT 2 +#define MJ2_CFMT 3 +#define PXM_DFMT 0 +#define PGX_DFMT 1 +#define BMP_DFMT 2 +#define YUV_DFMT 3 + +#define MAX_MESSAGE_LEN 200 + +/* check file type */ +int +jpeg2000familytype(unsigned char *hdr, int hdr_len) +{ + // check length + if (hdr_len < 24) + return -1; + + // check format + if (hdr[0] == 0x00 && + hdr[1] == 0x00 && + hdr[2] == 0x00 && + hdr[3] == 0x0C && + hdr[4] == 0x6A && + hdr[5] == 0x50 && + hdr[6] == 0x20 && + hdr[7] == 0x20 && + hdr[20] == 0x6A && + hdr[21] == 0x70 && + hdr[22] == 0x32) + // JP2 file format + return JP2_CFMT; + else if (hdr[0] == 0x00 && + hdr[1] == 0x00 && + hdr[2] == 0x00 && + hdr[3] == 0x0C && + hdr[4] == 0x6A && + hdr[5] == 0x50 && + hdr[6] == 0x20 && + hdr[7] == 0x20 && + hdr[20] == 0x6D && + hdr[21] == 0x6A && + hdr[22] == 0x70 && + hdr[23] == 0x32) + // MJ2 file format + return MJ2_CFMT; + else if (hdr[0] == 0xFF && + hdr[1] == 0x4F) + // J2K file format + return J2K_CFMT; + else + // unknown format + return -1; + +} + +/* we have to use this to avoid GUI-noGUI threads crashing */ +void printevent(const char *msg) +{ +#ifndef __WXGTK__ + wxMutexGuiEnter(); +#endif /* __WXGTK__ */ + wxLogMessage(wxT("%s"), msg); +#ifndef __WXGTK__ + wxMutexGuiLeave(); +#endif /* __WXGTK__ */ +} + +/* sample error callback expecting a FILE* client object */ +void jpeg2000_error_callback(const char *msg, void *client_data) { + char mess[MAX_MESSAGE_LEN + 20]; + int message_len = strlen(msg); + + if (message_len > MAX_MESSAGE_LEN) + message_len = MAX_MESSAGE_LEN; + + if (msg[message_len - 1] == '\n') + message_len--; + + sprintf(mess, "[ERROR] %.*s", message_len, msg); + printevent(mess); +} + +/* sample warning callback expecting a FILE* client object */ +void jpeg2000_warning_callback(const char *msg, void *client_data) { + char mess[MAX_MESSAGE_LEN + 20]; + int message_len = strlen(msg); + + if (message_len > MAX_MESSAGE_LEN) + message_len = MAX_MESSAGE_LEN; + + if (msg[message_len - 1] == '\n') + message_len--; + + sprintf(mess, "[WARNING] %.*s", message_len, msg); + printevent(mess); +} + +/* sample debug callback expecting no client object */ +void jpeg2000_info_callback(const char *msg, void *client_data) { + char mess[MAX_MESSAGE_LEN + 20]; + int message_len = strlen(msg); + + if (message_len > MAX_MESSAGE_LEN) + message_len = MAX_MESSAGE_LEN; + + if (msg[message_len - 1] == '\n') + message_len--; + + sprintf(mess, "[INFO] %.*s", message_len, msg); + printevent(mess); +} + +/* macro functions */ +/* From little endian to big endian, 2 and 4 bytes */ +#define BYTE_SWAP2(X) ((X & 0x00FF) << 8) | ((X & 0xFF00) >> 8) +#define BYTE_SWAP4(X) ((X & 0x000000FF) << 24) | ((X & 0x0000FF00) << 8) | ((X & 0x00FF0000) >> 8) | ((X & 0xFF000000) >> 24) + +#ifdef __WXGTK__ +#define BYTE_SWAP8(X) ((X & 0x00000000000000FFULL) << 56) | ((X & 0x000000000000FF00ULL) << 40) | \ + ((X & 0x0000000000FF0000ULL) << 24) | ((X & 0x00000000FF000000ULL) << 8) | \ + ((X & 0x000000FF00000000ULL) >> 8) | ((X & 0x0000FF0000000000ULL) >> 24) | \ + ((X & 0x00FF000000000000ULL) >> 40) | ((X & 0xFF00000000000000ULL) >> 56) +#else +#define BYTE_SWAP8(X) ((X & 0x00000000000000FF) << 56) | ((X & 0x000000000000FF00) << 40) | \ + ((X & 0x0000000000FF0000) << 24) | ((X & 0x00000000FF000000) << 8) | \ + ((X & 0x000000FF00000000) >> 8) | ((X & 0x0000FF0000000000) >> 24) | \ + ((X & 0x00FF000000000000) >> 40) | ((X & 0xFF00000000000000) >> 56) +#endif + +/* From codestream to int values */ +#define STREAM_TO_UINT32(C, P) (((unsigned long int) (C)[(P) + 0] << 24) + \ + ((unsigned long int) (C)[(P) + 1] << 16) + \ + ((unsigned long int) (C)[(P) + 2] << 8) + \ + ((unsigned long int) (C)[(P) + 3] << 0)) + +#define STREAM_TO_UINT16(C, P) (((unsigned long int) (C)[(P) + 0] << 8) + \ + ((unsigned long int) (C)[(P) + 1] << 0)) + +/* defines */ +#define SHORT_DESCR_LEN 32 +#define LONG_DESCR_LEN 256 + +/* enumeration for file formats */ +#define JPEG2000FILENUM 4 +typedef enum { + + JP2_FILE, + J2K_FILE, + MJ2_FILE, + UNK_FILE + +} jpeg2000filetype; + +/* enumeration for the box types */ +#define JPEG2000BOXNUM 23 +typedef enum { + + FILE_BOX, + JP_BOX, + FTYP_BOX, + JP2H_BOX, + IHDR_BOX, + COLR_BOX, + JP2C_BOX, + JP2I_BOX, + XML_BOX, + UUID_BOX, + UINF_BOX, + MOOV_BOX, + MVHD_BOX, + TRAK_BOX, + TKHD_BOX, + MDIA_BOX, + MINF_BOX, + STBL_BOX, + STSD_BOX, + MJP2_BOX, + MDAT_BOX, + ANY_BOX, + UNK_BOX + +} jpeg2000boxtype; + +/* jpeg2000 family box signatures */ +#define FILE_SIGN "" +#define JP_SIGN "jP\040\040" +#define FTYP_SIGN "ftyp" +#define JP2H_SIGN "jp2h" +#define IHDR_SIGN "ihdr" +#define COLR_SIGN "colr" +#define JP2C_SIGN "jp2c" +#define JP2I_SIGN "jp2i" +#define XML_SIGN "xml\040" +#define UUID_SIGN "uuid" +#define UINF_SIGN "uinf" +#define MOOV_SIGN "moov" +#define MVHD_SIGN "mvhd" +#define TRAK_SIGN "trak" +#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" +#define MDAT_SIGN "mdat" +#define ANY_SIGN "" +#define UNK_SIGN "" + +/* the box structure itself */ +struct jpeg2000boxdef { + + char value[5]; /* hexadecimal value/string*/ + char name[SHORT_DESCR_LEN]; /* short description */ + char descr[LONG_DESCR_LEN]; /* long description */ + int sbox; /* is it a superbox? */ + int req[JPEG2000FILENUM]; /* mandatory box */ + jpeg2000boxtype ins; /* contained in box... */ + +}; + +/* the possible boxes */ +struct jpeg2000boxdef jpeg2000box[] = +{ +/* sign */ {FILE_SIGN, +/* short */ "placeholder for nothing", +/* long */ "Nothing to say", +/* sbox */ 0, +/* req */ {1, 1, 1}, +/* ins */ FILE_BOX}, + +/* sign */ {JP_SIGN, +/* short */ "JPEG 2000 Signature box", +/* long */ "This box uniquely identifies the file as being part of the JPEG 2000 family of files", +/* sbox */ 0, +/* req */ {1, 1, 1}, +/* ins */ FILE_BOX}, + +/* sign */ {FTYP_SIGN, +/* short */ "File Type box", +/* long */ "This box specifies file type, version and compatibility information, including specifying if this file " + "is a conforming JP2 file or if it can be read by a conforming JP2 reader", +/* sbox */ 0, +/* req */ {1, 1, 1}, +/* ins */ FILE_BOX}, + +/* sign */ {JP2H_SIGN, +/* short */ "JP2 Header box", +/* long */ "This box contains a series of boxes that contain header-type information about the file", +/* sbox */ 1, +/* req */ {1, 1, 1}, +/* ins */ FILE_BOX}, + +/* sign */ {IHDR_SIGN, +/* short */ "Image Header box", +/* long */ "This box specifies the size of the image and other related fields", +/* sbox */ 0, +/* req */ {1, 1, 1}, +/* ins */ JP2H_BOX}, + +/* sign */ {COLR_SIGN, +/* short */ "Colour Specification box", +/* long */ "This box specifies the colourspace of the image", +/* sbox */ 0, +/* req */ {1, 1, 1}, +/* ins */ JP2H_BOX}, + +/* sign */ {JP2C_SIGN, +/* short */ "Contiguous Codestream box", +/* long */ "This box contains the codestream as defined by Annex A", +/* sbox */ 0, +/* req */ {1, 1, 1}, +/* ins */ FILE_BOX}, + +/* sign */ {JP2I_SIGN, +/* short */ "Intellectual Property box", +/* long */ "This box contains intellectual property information about the image", +/* sbox */ 0, +/* req */ {0, 0, 0}, +/* ins */ FILE_BOX}, + +/* sign */ {XML_SIGN, +/* short */ "XML box", +/* long */ "This box provides a tool by which vendors can add XML formatted information to a JP2 file", +/* sbox */ 0, +/* req */ {0, 0, 0}, +/* ins */ FILE_BOX}, + +/* sign */ {UUID_SIGN, +/* short */ "UUID box", +/* long */ "This box provides a tool by which vendors can add additional information to a file " + "without risking conflict with other vendors", +/* sbox */ 0, +/* req */ {0, 0, 0}, +/* ins */ FILE_BOX}, + +/* sign */ {UINF_SIGN, +/* short */ "UUID Info box", +/* long */ "This box provides a tool by which a vendor may provide access to additional information associated with a UUID", +/* sbox */ 0, +/* req */ {0, 0, 0}, +/* ins */ FILE_BOX}, + +/* sign */ {MOOV_SIGN, +/* short */ "Movie box", +/* long */ "This box contains the media data. In video tracks, this box would contain JPEG2000 video frames", +/* sbox */ 1, +/* req */ {1, 1, 1}, +/* ins */ FILE_BOX}, + +/* sign */ {MVHD_SIGN, +/* short */ "Movie Header box", +/* long */ "This box defines overall information which is media-independent, and relevant to the entire presentation " + "considered as a whole", +/* sbox */ 0, +/* req */ {1, 1, 1}, +/* ins */ MOOV_BOX}, + +/* sign */ {TRAK_SIGN, +/* short */ "Track box", +/* long */ "This is a container box for a single track of a presentation. A presentation may consist of one or more tracks", +/* sbox */ 1, +/* req */ {1, 1, 1}, +/* ins */ MOOV_BOX}, + +/* sign */ {TKHD_SIGN, +/* short */ "Track Header box", +/* long */ "This box specifies the characteristics of a single track. Exactly one Track Header Box is contained in a track", +/* sbox */ 0, +/* req */ {1, 1, 1}, +/* ins */ TRAK_BOX}, + +/* sign */ {MDIA_SIGN, +/* short */ "Media box", +/* long */ "The media declaration container contains all the objects which declare information about the media data " + "within a track", +/* sbox */ 1, +/* req */ {1, 1, 1}, +/* ins */ TRAK_BOX}, + +/* sign */ {MINF_SIGN, +/* short */ "Media Information box", +/* long */ "This box contains all the objects which declare characteristic information of the media in the track", +/* sbox */ 1, +/* req */ {1, 1, 1}, +/* ins */ MDIA_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", +/* sbox */ 1, +/* req */ {1, 1, 1}, +/* ins */ MINF_BOX}, + +/* sign */ {STSD_SIGN, +/* short */ "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 */ {MJP2_SIGN, +/* short */ "MJP2 Sample Description box", +/* long */ "The MJP2 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 */ {MDAT_SIGN, +/* short */ "Media Data box", +/* long */ "The meta-data for a presentation is stored in the single Movie Box which occurs at the top-level of a file", +/* sbox */ 1, +/* req */ {1, 1, 1}, +/* ins */ FILE_BOX}, + +/* sign */ {ANY_SIGN, +/* short */ "Any box", +/* long */ "All the existing boxes", +/* sbox */ 0, +/* req */ {0, 0, 0}, +/* ins */ FILE_BOX}, + +/* sign */ {UNK_SIGN, +/* short */ "Unknown Type box", +/* long */ "The signature is not recognised to be that of an existing box", +/* sbox */ 0, +/* req */ {0, 0, 0}, +/* ins */ ANY_BOX} + +}; + +/* declaration */ +int +jpeg2000_box_handler_function(jpeg2000boxtype boxtype, wxInputStream& stream, unsigned long int filepoint, + unsigned long int filelimit, int level, char *scansign, + unsigned long int *scanpoint); + +#ifdef __WXMSW__ +typedef unsigned __int64 int8byte; +#endif // __WXMSW__ + +#ifdef __WXGTK__ +typedef unsigned long long int8byte; +#endif // __WXGTK__ + +/* internal mini-search for a box signature */ +int +jpeg2000_file_parse(wxInputStream& stream, unsigned long int filepoint, unsigned long int filelimit, int level, + char *scansign, unsigned long int *scanpoint) +{ + unsigned long int LBox = 0x00000000; + char TBox[5] = "\0\0\0\0"; + int8byte XLBox = 0x0000000000000000; + unsigned long int box_length = 0; + int last_box = 0, box_num = 0; + int box_type = ANY_BOX; + unsigned char fourbytes[4]; + int box_number = 0; + + /* cycle all over the file */ + box_num = 0; + last_box = 0; + while (!last_box) { + + /* do not exceed file limit */ + if (filepoint >= filelimit) + return (0); + + /* seek on file */ + if (stream.SeekI(filepoint, wxFromStart) == wxInvalidOffset) + return (-1); + + /* read the mandatory LBox, 4 bytes */ + if (!stream.Read(fourbytes, 4)) { + wxLogError(wxT("Problem reading LBox from the file (file ended?)")); + return -1; + }; + LBox = STREAM_TO_UINT32(fourbytes, 0); + + /* read the mandatory TBox, 4 bytes */ + if (!stream.Read(TBox, 4)) { + wxLogError(wxT("Problem reading TBox from the file (file ended?)")); + return -1; + }; + + /* look if scansign is got */ + if ((scansign != NULL) && (memcmp(TBox, scansign, 4) == 0)) { + /* hack/exploit */ + // stop as soon as you find the level-th codebox + if (box_number == level) { + memcpy(scansign, " ", 4); + *scanpoint = filepoint; + return (0); + } else + box_number++; + + }; + + /* determine the box type */ + for (box_type = JP_BOX; box_type < UNK_BOX; box_type++) + if (memcmp(TBox, jpeg2000box[box_type].value, 4) == 0) + break; + + /* read the optional XLBox, 8 bytes */ + if (LBox == 1) { + + if (!stream.Read(&XLBox, 8)) { + wxLogError(wxT("Problem reading XLBox from the file (file ended?)")); + return -1; + }; + box_length = (unsigned long int) BYTE_SWAP8(XLBox); + + } else if (LBox == 0x00000000) { + + /* last box in file */ + last_box = 1; + box_length = filelimit - filepoint; + + } else + + box_length = LBox; + + + /* go deep in the box */ + jpeg2000_box_handler_function((jpeg2000boxtype) box_type, + stream, (LBox == 1) ? (filepoint + 16) : (filepoint + 8), + filepoint + box_length, level, scansign, scanpoint); + + /* if it's a superbox go inside it */ + if (jpeg2000box[box_type].sbox) + jpeg2000_file_parse(stream, (LBox == 1) ? (filepoint + 16) : (filepoint + 8), filepoint + box_length, + level, scansign, scanpoint); + + /* increment box number and filepoint*/ + box_num++; + filepoint += box_length; + + }; + + /* all good */ + return (0); +} + +// search first contiguos codestream box in an mj2 file +unsigned long int +searchjpeg2000c(wxInputStream& stream, unsigned long int fsize, int number) +{ + char scansign[] = "jp2c"; + unsigned long int scanpoint = 0L; + + wxLogMessage(wxT("Searching jp2c box... ")); + + /* do the parsing */ + if (jpeg2000_file_parse(stream, 0, fsize, number, scansign, &scanpoint) < 0) + wxLogMessage(wxT("Unrecoverable error during JPEG 2000 box parsing: stopping")); + + if (strcmp(scansign, " ")) + wxLogMessage(wxT("Box not found")); + else { + + wxLogMessage(wxString::Format(wxT("Box found at byte %d"), scanpoint)); + + }; + + return (scanpoint); +} + +// search the jp2h box in the file +unsigned long int +searchjpeg2000headerbox(wxInputStream& stream, unsigned long int fsize) +{ + char scansign[] = "jp2h"; + unsigned long int scanpoint = 0L; + + wxLogMessage(wxT("Searching jp2h box... ")); + + /* do the parsing */ + if (jpeg2000_file_parse(stream, 0, fsize, 0, scansign, &scanpoint) < 0) + wxLogMessage(wxT("Unrecoverable error during JPEG 2000 box parsing: stopping")); + + if (strcmp(scansign, " ")) + wxLogMessage(wxT("Box not found")); + else + wxLogMessage(wxString::Format(wxT("Box found at byte %d"), scanpoint)); + + return (scanpoint); +} + +/* handling functions */ +#define ITEM_PER_ROW 10 + +/* Box handler function */ +int +jpeg2000_box_handler_function(jpeg2000boxtype boxtype, wxInputStream& stream, unsigned long int filepoint, + unsigned long int filelimit, int level, + char *scansign, unsigned long int *scanpoint) +{ + switch (boxtype) { + + /* Sample Description box */ + case (STSD_BOX): + jpeg2000_file_parse(stream, filepoint + 8, filelimit, level, scansign, scanpoint); + break; + + /* MJP2 Sample Description box */ + case (MJP2_BOX): + jpeg2000_file_parse(stream, filepoint + 78, filelimit, level, scansign, scanpoint); + break; + + /* not yet implemented */ + default: + break; + + }; + + return (0); +} + +// the jP and ftyp parts of the header +#define jpeg2000headSIZE 32 +unsigned char jpeg2000head[jpeg2000headSIZE] = { + 0x00, 0x00, 0x00, 0x0C, 'j', 'P', ' ', ' ', + 0x0D, 0x0A, 0x87, 0x0A, 0x00, 0x00, 0x00, 0x14, + 'f', 't', 'y', 'p', 'j', 'p', '2', ' ', + 0x00, 0x00, 0x00, 0x00, 'j', 'p', '2', ' ' +}; + +///////////////////////////////////////////////// +///////////////////////////////////////////////// + +// load the jpeg2000 file format +bool wxJPEG2000Handler::LoadFile(wxImage *image, wxInputStream& stream, bool verbose, int index) +{ + opj_dparameters_t parameters; /* decompression parameters */ + opj_event_mgr_t event_mgr; /* event manager */ + opj_image_t *opjimage = NULL; + unsigned char *src = NULL; + unsigned char *ptr; + int file_length, jp2c_point, jp2h_point; + unsigned long int jp2hboxlen, jp2cboxlen; + opj_codestream_info_t cstr_info; /* Codestream information structure */ + unsigned char hdr[24]; + int jpfamform; + + // destroy the image + image->Destroy(); + + /* read the beginning of the file to check the type */ + if (!stream.Read(hdr, WXSIZEOF(hdr))) + return false; + if ((jpfamform = jpeg2000familytype(hdr, WXSIZEOF(hdr))) < 0) + return false; + stream.SeekI(0, wxFromStart); + + /* handle to a decompressor */ + opj_dinfo_t* dinfo = NULL; + opj_cio_t *cio = NULL; + + /* configure the event callbacks */ + memset(&event_mgr, 0, sizeof(opj_event_mgr_t)); + event_mgr.error_handler = jpeg2000_error_callback; + event_mgr.warning_handler = jpeg2000_warning_callback; + event_mgr.info_handler = jpeg2000_info_callback; + + /* set decoding parameters to default values */ + opj_set_default_decoder_parameters(¶meters); + + /* prepare parameters */ + strncpy(parameters.infile, "", sizeof(parameters.infile) - 1); + strncpy(parameters.outfile, "", sizeof(parameters.outfile) - 1); + parameters.decod_format = jpfamform; + 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 */ + if (jpfamform == JP2_CFMT || jpfamform == MJ2_CFMT) + dinfo = opj_create_decompress(CODEC_JP2); + else if (jpfamform == J2K_CFMT) + dinfo = opj_create_decompress(CODEC_J2K); + else + return false; + + /* find length of the stream */ + stream.SeekI(0, wxFromEnd); + file_length = (int) stream.TellI(); + + /* it's a movie */ + if (jpfamform == MJ2_CFMT) { + /* search for the first codestream box and the movie header box */ + jp2c_point = searchjpeg2000c(stream, file_length, m_framenum); + jp2h_point = searchjpeg2000headerbox(stream, file_length); + + // read the jp2h box and store it + stream.SeekI(jp2h_point, wxFromStart); + stream.Read(&jp2hboxlen, sizeof(unsigned long int)); + jp2hboxlen = BYTE_SWAP4(jp2hboxlen); + + // read the jp2c box and store it + stream.SeekI(jp2c_point, wxFromStart); + stream.Read(&jp2cboxlen, sizeof(unsigned long int)); + jp2cboxlen = BYTE_SWAP4(jp2cboxlen); + + // malloc memory source + src = (unsigned char *) malloc(jpeg2000headSIZE + jp2hboxlen + jp2cboxlen); + + // copy the jP and ftyp + memcpy(src, jpeg2000head, jpeg2000headSIZE); + + // copy the jp2h + stream.SeekI(jp2h_point, wxFromStart); + stream.Read(&src[jpeg2000headSIZE], jp2hboxlen); + + // copy the jp2c + stream.SeekI(jp2c_point, wxFromStart); + stream.Read(&src[jpeg2000headSIZE + jp2hboxlen], jp2cboxlen); + } else if (jpfamform == JP2_CFMT || jpfamform == J2K_CFMT) { + /* It's a plain image */ + /* get data */ + stream.SeekI(0, wxFromStart); + src = (unsigned char *) malloc(file_length); + stream.Read(src, file_length); + } else + return false; + + /* catch events using our callbacks and give a local context */ + opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, stderr); + + /* setup the decoder decoding parameters using user parameters */ + opj_setup_decoder(dinfo, ¶meters); + + /* open a byte stream */ + if (jpfamform == MJ2_CFMT) + cio = opj_cio_open((opj_common_ptr)dinfo, src, jpeg2000headSIZE + jp2hboxlen + jp2cboxlen); + else if (jpfamform == JP2_CFMT || jpfamform == J2K_CFMT) + cio = opj_cio_open((opj_common_ptr)dinfo, src, file_length); + else { + free(src); + return false; + } + + /* decode the stream and fill the image structure */ + opjimage = opj_decode_with_info(dinfo, cio, &cstr_info); + if (!opjimage) { + wxMutexGuiEnter(); + wxLogError(wxT("JPEG 2000 failed to decode image!")); + wxMutexGuiLeave(); + opj_destroy_decompress(dinfo); + opj_cio_close(cio); + free(src); + return false; + } + + /* close the byte stream */ + opj_cio_close(cio); + + /* + + - At this point, we have the structure "opjimage" that is filled with decompressed + data, as processed by the OpenJPEG decompression engine + + - We need to fill the class "image" with the proper pixel sample values + + */ + { + int shiftbpp; + int c, tempcomps; + + // check components number + if (m_components > opjimage->numcomps) + m_components = opjimage->numcomps; + + // check image depth (only on the first one, for now) + if (m_components) + shiftbpp = opjimage->comps[m_components - 1].prec - 8; + else + shiftbpp = opjimage->comps[0].prec - 8; + + // prepare image size + if (m_components) + image->Create(opjimage->comps[m_components - 1].w, opjimage->comps[m_components - 1].h, true); + else + image->Create(opjimage->comps[0].w, opjimage->comps[0].h, true); + + // access image raw data + image->SetMask(false); + ptr = image->GetData(); + + // workaround for components different from 1 or 3 + if ((opjimage->numcomps != 1) && (opjimage->numcomps != 3)) { +#ifndef __WXGTK__ + wxMutexGuiEnter(); +#endif /* __WXGTK__ */ + wxLogMessage(wxT("JPEG2000: weird number of components")); +#ifndef __WXGTK__ + wxMutexGuiLeave(); +#endif /* __WXGTK__ */ + tempcomps = 1; + } else + tempcomps = opjimage->numcomps; + + // workaround for subsampled components + for (c = 1; c < tempcomps; c++) { + if ((opjimage->comps[c].w != opjimage->comps[c - 1].w) || (opjimage->comps[c].h != opjimage->comps[c - 1].h)) { + tempcomps = 1; + break; + } + } + + // workaround for different precision components + for (c = 1; c < tempcomps; c++) { + if (opjimage->comps[c].bpp != opjimage->comps[c - 1].bpp) { + tempcomps = 1; + break; + } + } + + // only one component selected + if (m_components) + tempcomps = 1; + + // RGB color picture + if (tempcomps == 3) { + int row, col; + int *r = opjimage->comps[0].data; + int *g = opjimage->comps[1].data; + int *b = opjimage->comps[2].data; + if (shiftbpp > 0) { + for (row = 0; row < opjimage->comps[0].h; row++) { + for (col = 0; col < opjimage->comps[0].w; col++) { + + *(ptr++) = (*(r++)) >> shiftbpp; + *(ptr++) = (*(g++)) >> shiftbpp; + *(ptr++) = (*(b++)) >> shiftbpp; + + } + } + + } else if (shiftbpp < 0) { + for (row = 0; row < opjimage->comps[0].h; row++) { + for (col = 0; col < opjimage->comps[0].w; col++) { + + *(ptr++) = (*(r++)) << -shiftbpp; + *(ptr++) = (*(g++)) << -shiftbpp; + *(ptr++) = (*(b++)) << -shiftbpp; + + } + } + + } else { + for (row = 0; row < opjimage->comps[0].h; row++) { + for (col = 0; col < opjimage->comps[0].w; col++) { + + *(ptr++) = *(r++); + *(ptr++) = *(g++); + *(ptr++) = *(b++); + + } + } + } + } + + // B/W picture + if (tempcomps == 1) { + int row, col; + int selcomp; + + if (m_components) + selcomp = m_components - 1; + else + selcomp = 0; + + int *y = opjimage->comps[selcomp].data; + if (shiftbpp > 0) { + for (row = 0; row < opjimage->comps[selcomp].h; row++) { + for (col = 0; col < opjimage->comps[selcomp].w; col++) { + + *(ptr++) = (*(y)) >> shiftbpp; + *(ptr++) = (*(y)) >> shiftbpp; + *(ptr++) = (*(y++)) >> shiftbpp; + + } + } + } else if (shiftbpp < 0) { + for (row = 0; row < opjimage->comps[selcomp].h; row++) { + for (col = 0; col < opjimage->comps[selcomp].w; col++) { + + *(ptr++) = (*(y)) << -shiftbpp; + *(ptr++) = (*(y)) << -shiftbpp; + *(ptr++) = (*(y++)) << -shiftbpp; + + } + } + } else { + for (row = 0; row < opjimage->comps[selcomp].h; row++) { + for (col = 0; col < opjimage->comps[selcomp].w; col++) { + + *(ptr++) = *(y); + *(ptr++) = *(y); + *(ptr++) = *(y++); + + } + } + } + } + + + } + + wxMutexGuiEnter(); + wxLogMessage(wxT("JPEG 2000 image loaded.")); + wxMutexGuiLeave(); + + /* close openjpeg structs */ + opj_destroy_decompress(dinfo); + opj_image_destroy(opjimage); + free(src); + + if (!image->Ok()) + return false; + else + return true; + +} + +#define CINEMA_24_CS 1302083 /* Codestream length for 24fps */ +#define CINEMA_48_CS 651041 /* Codestream length for 48fps */ +#define COMP_24_CS 1041666 /* Maximum size per color component for 2K & 4K @ 24fps */ +#define COMP_48_CS 520833 /* Maximum size per color component for 2K @ 48fps */ + +// save the j2k codestream +bool wxJPEG2000Handler::SaveFile( wxImage *wimage, wxOutputStream& stream, bool verbose ) +{ + opj_cparameters_t parameters; /* compression parameters */ + opj_event_mgr_t event_mgr; /* event manager */ + opj_image_t *oimage = NULL; + opj_image_cmptparm_t *cmptparm; + opj_cio_t *cio = NULL; + opj_codestream_info_t cstr_info; + int codestream_length; + bool bSuccess; + int i; + char indexfilename[OPJ_PATH_LEN] = ""; /* index file name */ + + /* + configure the event callbacks (not required) + setting of each callback is optionnal + */ + memset(&event_mgr, 0, sizeof(opj_event_mgr_t)); + event_mgr.error_handler = jpeg2000_error_callback; + event_mgr.warning_handler = jpeg2000_warning_callback; + event_mgr.info_handler = jpeg2000_info_callback; + + /* set encoding parameters to default values */ + opj_set_default_encoder_parameters(¶meters); + + /* load parameters */ + parameters.cp_cinema = OFF; + + /* subsampling */ + if (sscanf(m_subsampling.ToAscii(), "%d,%d", &(parameters.subsampling_dx), &(parameters.subsampling_dy)) != 2) { + wxLogError(wxT("Wrong sub-sampling encoder setting: dx,dy")); + return false; + } + + /* compression rates */ + if ((m_rates != wxT("")) && (!m_enablequality)) { + const char *s1 = m_rates.ToAscii(); + wxLogMessage(wxT("rates %s"), s1); + while (sscanf(s1, "%f", &(parameters.tcp_rates[parameters.tcp_numlayers])) == 1) { + parameters.tcp_numlayers++; + while (*s1 && *s1 != ',') { + s1++; + } + if (!*s1) + break; + s1++; + } + wxLogMessage(wxT("%d layers"), parameters.tcp_numlayers); + parameters.cp_disto_alloc = 1; + } + + /* image quality, dB */ + if ((m_quality != wxT("")) && (m_enablequality)) { + const char *s2 = m_quality.ToAscii(); + wxLogMessage(wxT("qualities %s"), s2); + while (sscanf(s2, "%f", ¶meters.tcp_distoratio[parameters.tcp_numlayers]) == 1) { + parameters.tcp_numlayers++; + while (*s2 && *s2 != ',') { + s2++; + } + if (!*s2) + break; + s2++; + } + wxLogMessage(wxT("%d layers"), parameters.tcp_numlayers); + parameters.cp_fixed_quality = 1; + } + + /* image origin */ + if (sscanf(m_origin.ToAscii(), "%d,%d", ¶meters.image_offset_x0, ¶meters.image_offset_y0) != 2) { + wxLogError(wxT("bad coordinate of the image origin: x0,y0")); + return false; + } + + /* Create comment for codestream */ + if(m_enablecomm) { + parameters.cp_comment = (char *) malloc(strlen(m_comment.ToAscii()) + 1); + if(parameters.cp_comment) { + strcpy(parameters.cp_comment, m_comment.ToAscii()); + } + } else { + parameters.cp_comment = NULL; + } + + /* indexing file */ + if (m_enableidx) { + strncpy(indexfilename, m_index.ToAscii(), OPJ_PATH_LEN); + wxLogMessage(wxT("index file is %s"), indexfilename); + } + + /* if no rate entered, lossless by default */ + if (parameters.tcp_numlayers == 0) { + parameters.tcp_rates[0] = 0; /* MOD antonin : losslessbug */ + parameters.tcp_numlayers++; + parameters.cp_disto_alloc = 1; + } + + /* irreversible transform */ + parameters.irreversible = (m_irreversible == true) ? 1 : 0; + + /* resolutions */ + parameters.numresolution = m_resolutions; + + /* codeblocks size */ + if (m_cbsize != wxT("")) { + int cblockw_init = 0, cblockh_init = 0; + sscanf(m_cbsize.ToAscii(), "%d,%d", &cblockw_init, &cblockh_init); + if (cblockw_init * cblockh_init > 4096 || cblockw_init > 1024 || cblockw_init < 4 || cblockh_init > 1024 || cblockh_init < 4) { + wxLogError(wxT("!! Size of code_block error !! Restrictions:\n width*height<=4096\n 4<=width,height<= 1024")); + return false; + } + parameters.cblockw_init = cblockw_init; + parameters.cblockh_init = cblockh_init; + } + + /* precincts size */ + if (m_prsize != wxT("")) { + char sep; + int res_spec = 0; + char *s = (char *) m_prsize.c_str(); + do { + sep = 0; + sscanf(s, "[%d,%d]%c", ¶meters.prcw_init[res_spec], ¶meters.prch_init[res_spec], &sep); + parameters.csty |= 0x01; + res_spec++; + s = strpbrk(s, "]") + 2; + } while (sep == ','); + parameters.res_spec = res_spec; + } + + /* tiles */ + if (m_tsize != wxT("")) { + sscanf(m_tsize.ToAscii(), "%d,%d", ¶meters.cp_tdx, ¶meters.cp_tdy); + parameters.tile_size_on = true; + } + + /* tile origin */ + if (sscanf(m_torigin.ToAscii(), "%d,%d", ¶meters.cp_tx0, ¶meters.cp_ty0) != 2) { + wxLogError(wxT("tile offset setting error: X0,Y0")); + return false; + } + + /* use SOP */ + if (m_enablesop) + parameters.csty |= 0x02; + + /* use EPH */ + if (m_enableeph) + parameters.csty |= 0x04; + + /* multiple component transform */ + if (m_multicomp) + parameters.tcp_mct = 1; + else + parameters.tcp_mct = 0; + + /* mode switch */ + parameters.mode = (m_enablebypass ? 1 : 0) + (m_enablereset ? 2 : 0) + + (m_enablerestart ? 4 : 0) + (m_enablevsc ? 8 : 0) + + (m_enableerterm ? 16 : 0) + (m_enablesegmark ? 32 : 0); + + /* progression order */ + switch (m_progression) { + + /* LRCP */ + case 0: + parameters.prog_order = LRCP; + break; + + /* RLCP */ + case 1: + parameters.prog_order = RLCP; + break; + + /* RPCL */ + case 2: + parameters.prog_order = RPCL; + break; + + /* PCRL */ + case 3: + parameters.prog_order = PCRL; + break; + + /* CPRL */ + case 4: + parameters.prog_order = CPRL; + break; + + /* DCI2K24 */ + case 5: + parameters.cp_cinema = CINEMA2K_24; + parameters.cp_rsiz = CINEMA2K; + break; + + /* DCI2K48 */ + case 6: + parameters.cp_cinema = CINEMA2K_48; + parameters.cp_rsiz = CINEMA2K; + break; + + /* DCI4K */ + case 7: + parameters.cp_cinema = CINEMA4K_24; + parameters.cp_rsiz = CINEMA4K; + break; + + default: + break; + } + + /* check cinema */ + if (parameters.cp_cinema) { + + /* set up */ + parameters.tile_size_on = false; + parameters.cp_tdx=1; + parameters.cp_tdy=1; + + /*Tile part*/ + parameters.tp_flag = 'C'; + parameters.tp_on = 1; + + /*Tile and Image shall be at (0,0)*/ + parameters.cp_tx0 = 0; + parameters.cp_ty0 = 0; + parameters.image_offset_x0 = 0; + parameters.image_offset_y0 = 0; + + /*Codeblock size= 32*32*/ + parameters.cblockw_init = 32; + parameters.cblockh_init = 32; + parameters.csty |= 0x01; + + /*The progression order shall be CPRL*/ + parameters.prog_order = CPRL; + + /* No ROI */ + parameters.roi_compno = -1; + + parameters.subsampling_dx = 1; + parameters.subsampling_dy = 1; + + /* 9-7 transform */ + parameters.irreversible = 1; + + } + + /* convert wx image into opj image */ + cmptparm = (opj_image_cmptparm_t*) malloc(3 * sizeof(opj_image_cmptparm_t)); + + /* initialize opj image components */ + memset(&cmptparm[0], 0, 3 * sizeof(opj_image_cmptparm_t)); + for(i = 0; i < 3; i++) { + cmptparm[i].prec = 8; + cmptparm[i].bpp = 8; + cmptparm[i].sgnd = false; + cmptparm[i].dx = parameters.subsampling_dx; + cmptparm[i].dy = parameters.subsampling_dy; + cmptparm[i].w = wimage->GetWidth(); + cmptparm[i].h = wimage->GetHeight(); + } + + /* create the image */ + oimage = opj_image_create(3, &cmptparm[0], CLRSPC_SRGB); + if(!oimage) { + if (cmptparm) + free(cmptparm); + return false; + } + + /* set image offset and reference grid */ + oimage->x0 = parameters.image_offset_x0; + oimage->y0 = parameters.image_offset_y0; + oimage->x1 = parameters.image_offset_x0 + (wimage->GetWidth() - 1) * 1 + 1; + oimage->y1 = parameters.image_offset_y0 + (wimage->GetHeight() - 1) * 1 + 1; + + /* load image data */ + unsigned char *value = wimage->GetData(); + int area = wimage->GetWidth() * wimage->GetHeight(); + for (i = 0; i < area; i++) { + oimage->comps[0].data[i] = *(value++); + oimage->comps[1].data[i] = *(value++); + oimage->comps[2].data[i] = *(value++); + } + + /* check cinema again */ + if (parameters.cp_cinema) { + int i; + float temp_rate; + opj_poc_t *POC = NULL; + + switch (parameters.cp_cinema) { + + case CINEMA2K_24: + case CINEMA2K_48: + if (parameters.numresolution > 6) { + parameters.numresolution = 6; + } + if (!((oimage->comps[0].w == 2048) | (oimage->comps[0].h == 1080))) { + wxLogWarning(wxT("Image coordinates %d x %d is not 2K compliant. JPEG Digital Cinema Profile-3 " + "(2K profile) compliance requires that at least one of coordinates match 2048 x 1080"), + oimage->comps[0].w, oimage->comps[0].h); + parameters.cp_rsiz = STD_RSIZ; + } + break; + + case CINEMA4K_24: + if (parameters.numresolution < 1) { + parameters.numresolution = 1; + } else if (parameters.numresolution > 7) { + parameters.numresolution = 7; + } + if (!((oimage->comps[0].w == 4096) | (oimage->comps[0].h == 2160))) { + wxLogWarning(wxT("Image coordinates %d x %d is not 4K compliant. JPEG Digital Cinema Profile-4" + "(4K profile) compliance requires that at least one of coordinates match 4096 x 2160"), + oimage->comps[0].w, oimage->comps[0].h); + parameters.cp_rsiz = STD_RSIZ; + } + parameters.POC[0].tile = 1; + parameters.POC[0].resno0 = 0; + parameters.POC[0].compno0 = 0; + parameters.POC[0].layno1 = 1; + parameters.POC[0].resno1 = parameters.numresolution - 1; + parameters.POC[0].compno1 = 3; + parameters.POC[0].prg1 = CPRL; + parameters.POC[1].tile = 1; + parameters.POC[1].resno0 = parameters.numresolution - 1; + parameters.POC[1].compno0 = 0; + parameters.POC[1].layno1 = 1; + parameters.POC[1].resno1 = parameters.numresolution; + parameters.POC[1].compno1 = 3; + parameters.POC[1].prg1 = CPRL; + parameters.numpocs = 2; + break; + } + + switch (parameters.cp_cinema) { + case CINEMA2K_24: + case CINEMA4K_24: + for (i = 0 ; i < parameters.tcp_numlayers; i++) { + temp_rate = 0; + if (parameters.tcp_rates[i] == 0) { + parameters.tcp_rates[0] = ((float) (oimage->numcomps * oimage->comps[0].w * oimage->comps[0].h * oimage->comps[0].prec)) / + (CINEMA_24_CS * 8 * oimage->comps[0].dx * oimage->comps[0].dy); + }else{ + temp_rate = ((float) (oimage->numcomps * oimage->comps[0].w * oimage->comps[0].h * oimage->comps[0].prec)) / + (parameters.tcp_rates[i] * 8 * oimage->comps[0].dx * oimage->comps[0].dy); + if (temp_rate > CINEMA_24_CS ) { + parameters.tcp_rates[i]= ((float) (oimage->numcomps * oimage->comps[0].w * oimage->comps[0].h * oimage->comps[0].prec)) / + (CINEMA_24_CS * 8 * oimage->comps[0].dx * oimage->comps[0].dy); + } else { + /* do nothing */ + } + } + } + parameters.max_comp_size = COMP_24_CS; + break; + + case CINEMA2K_48: + for (i = 0; i < parameters.tcp_numlayers; i++) { + temp_rate = 0 ; + if (parameters.tcp_rates[i] == 0) { + parameters.tcp_rates[0] = ((float) (oimage->numcomps * oimage->comps[0].w * oimage->comps[0].h * oimage->comps[0].prec)) / + (CINEMA_48_CS * 8 * oimage->comps[0].dx * oimage->comps[0].dy); + }else{ + temp_rate =((float) (oimage->numcomps * oimage->comps[0].w * oimage->comps[0].h * oimage->comps[0].prec)) / + (parameters.tcp_rates[i] * 8 * oimage->comps[0].dx * oimage->comps[0].dy); + if (temp_rate > CINEMA_48_CS ){ + parameters.tcp_rates[0]= ((float) (oimage->numcomps * oimage->comps[0].w * oimage->comps[0].h * oimage->comps[0].prec)) / + (CINEMA_48_CS * 8 * oimage->comps[0].dx * oimage->comps[0].dy); + }else{ + /* do nothing */ + } + } + } + parameters.max_comp_size = COMP_48_CS; + break; + } + + parameters.cp_disto_alloc = 1; + } + + /* get a J2K compressor handle */ + opj_cinfo_t* cinfo = opj_create_compress(CODEC_J2K); + + /* catch events using our callbacks and give a local context */ + opj_set_event_mgr((opj_common_ptr)cinfo, &event_mgr, stderr); + + /* setup the encoder parameters using the current image and user parameters */ + opj_setup_encoder(cinfo, ¶meters, oimage); + + /* open a byte stream for writing */ + /* allocate memory for all tiles */ + cio = opj_cio_open((opj_common_ptr)cinfo, NULL, 0); + + /* encode the image */ + bSuccess = opj_encode_with_info(cinfo, cio, oimage, &cstr_info); + if (!bSuccess) { + + opj_cio_close(cio); + opj_destroy_compress(cinfo); + opj_image_destroy(oimage); + if (cmptparm) + free(cmptparm); + if(parameters.cp_comment) + free(parameters.cp_comment); + if(parameters.cp_matrice) + free(parameters.cp_matrice); + +#ifndef __WXGTK__ + wxMutexGuiEnter(); +#endif /* __WXGTK__ */ + + wxLogError(wxT("failed to encode image")); + +#ifndef __WXGTK__ + wxMutexGuiLeave(); +#endif /* __WXGTK__ */ + + return false; + } + codestream_length = cio_tell(cio); + wxLogMessage(wxT("Codestream: %d bytes"), codestream_length); + + /* write the buffer to stream */ + stream.Write(cio->buffer, codestream_length); + + /* close and free the byte stream */ + opj_cio_close(cio); + + /* Write the index to disk */ + if (*indexfilename) { + if (write_index_file(&cstr_info, indexfilename)) { + wxLogError(wxT("Failed to output index file")); + } + } + + /* free remaining compression structures */ + opj_destroy_compress(cinfo); + + /* free image data */ + opj_image_destroy(oimage); + + if (cmptparm) + free(cmptparm); + if(parameters.cp_comment) + free(parameters.cp_comment); + if(parameters.cp_matrice) + free(parameters.cp_matrice); + +#ifndef __WXGTK__ + wxMutexGuiEnter(); +#endif /* __WXGTK__ */ + + wxLogMessage(wxT("J2K: Image encoded!")); + +#ifndef __WXGTK__ + wxMutexGuiLeave(); +#endif /* __WXGTK__ */ + + return true; +} + +#ifdef __VISUALC__ + #pragma warning(default:4611) +#endif /* VC++ */ + +// recognize the JPEG 2000 family starting box or the 0xFF4F JPEG 2000 SOC marker +bool wxJPEG2000Handler::DoCanRead(wxInputStream& stream) +{ + unsigned char hdr[24]; + int jpfamform; + + if ( !stream.Read(hdr, WXSIZEOF(hdr)) ) + return false; + + jpfamform = jpeg2000familytype(hdr, WXSIZEOF(hdr)); + + return ((jpfamform == JP2_CFMT) || (jpfamform == MJ2_CFMT) || (jpfamform == J2K_CFMT)); +} + +#endif // wxUSE_STREAMS + +#endif // wxUSE_LIBOPENJPEG diff --git a/applications/OPJViewer/source/imagjpeg2000.h b/applications/OPJViewer/source/imagjpeg2000.h index 2fea20a8..aad1ce32 100644 --- a/applications/OPJViewer/source/imagjpeg2000.h +++ b/applications/OPJViewer/source/imagjpeg2000.h @@ -1,177 +1,177 @@ -/* - * Copyright (c) 2007, Digital Signal Processing Laboratory, Università degli studi di Perugia (UPG), Italy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are 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. - */ -///////////////////////////////////////////////////////////////////////////// -// Name: imagalljpeg2000.h -// Purpose: wxImage JPEG 2000 family file format handler -// Author: G. Baruffa - based on imagjpeg.h, Vaclav Slavik -// RCS-ID: $Id: imagalljpeg2000.h,v 0.0 2008/01/31 11:22:00 VZ Exp $ -// Copyright: (c) Giuseppe Baruffa -// Licence: wxWindows licence -///////////////////////////////////////////////////////////////////////////// - -#ifndef _WX_IMAGJPEG2000_H_ -#define _WX_IMAGJPEG2000_H_ - -#include "wx/defs.h" - -//----------------------------------------------------------------------------- -// wxJPEG2000Handler -//----------------------------------------------------------------------------- - -#if wxUSE_LIBOPENJPEG - -#include "wx/image.h" -#include "libopenjpeg/openjpeg.h" -#include "codec/index.h" - -#define wxBITMAP_TYPE_JPEG2000 50 - -class WXDLLEXPORT wxJPEG2000Handler: public wxImageHandler -{ -public: - inline wxJPEG2000Handler() - { - m_name = wxT("JPEG 2000 family file format"); - m_extension = wxT("mj2"); - m_type = wxBITMAP_TYPE_JPEG2000; - m_mime = wxT("image/mj2"); - - /* decoding */ - 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 - - /* encoding */ - m_subsampling = wxT("1,1"); - m_origin = wxT("0,0"); - m_rates = wxT("20,10,5"); - m_quality = wxT("30,35,40"); - m_enablequality = false; - m_multicomp = false; - m_irreversible = false; - m_resolutions = 6; - m_progression = 0; - m_cbsize = wxT("32,32"); - m_prsize = wxT("[128,128],[128,128]"); - m_tsize = wxT(""); - m_torigin = wxT("0,0"); - /*m_progression - m_resilience*/ - m_enablesop = false; - m_enableeph = false; - m_enablereset = false; - m_enablesegmark = false; - m_enablevsc = false; - m_enablerestart = false; - m_enableerterm = false; - m_enablebypass = false; - /*m_roicompo - m_roiup - m_indexfname*/ - m_enableidx = false; - m_index = wxT("index.txt"); - m_enablepoc = false; - m_poc = wxT("T1=0,0,1,5,3,CPRL/T1=5,0,1,6,3,CPRL"); - m_enablecomm = true; - -#if defined __WXMSW__ - m_comment = wxT("Created by OPJViewer Win32 - OpenJPEG version "); -#elif defined __WXGTK__ - m_comment = wxT("Created by OPJViewer Lin32 - OpenJPEG version "); -#else - m_comment = wxT("Created by OPJViewer - OpenJPEG version "); -#endif - -#ifdef USE_JPWL - m_comment += wxString::Format(wxT("%s with JPWL"), (char *) opj_version()); -#else - m_comment += wxString::Format(wxT("%s"), (char *) opj_version()); -#endif - - } - - // decoding engine parameters - int m_reducefactor, m_qualitylayers, m_components, m_framenum; -#ifdef USE_JPWL - bool m_enablejpwl; - int m_expcomps, m_maxtiles; -#endif // USE_JPWL - - // encoding engine parameters - wxString m_subsampling; - wxString m_origin; - wxString m_rates; - wxString m_quality; - bool m_enablequality; - bool m_multicomp; - bool m_irreversible; - int m_resolutions; - int m_progression; - wxString m_cbsize; - wxString m_prsize; - wxString m_tsize; - wxString m_torigin; - /*m_progression - m_resilience*/ - bool m_enablesop; - bool m_enableeph; - bool m_enablebypass; - bool m_enableerterm; - bool m_enablerestart; - bool m_enablereset; - bool m_enablesegmark; - bool m_enablevsc; - /*m_roicompo - m_roiup - m_indexfname*/ - bool m_enableidx; - wxString m_index; - bool m_enablecomm; - wxString m_comment; - bool m_enablepoc; - wxString m_poc; - -#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); -protected: - virtual bool DoCanRead(wxInputStream& stream); -#endif - -private: - OPJ_PROG_ORDER give_progression(char progression[4]); - DECLARE_DYNAMIC_CLASS(wxJPEG2000Handler) -}; - -#endif // wxUSE_LIBOPENJPEG - -#endif // _WX_IMAGJPEG2000_H_ - +/* + * Copyright (c) 2007, Digital Signal Processing Laboratory, Università degli studi di Perugia (UPG), Italy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are 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. + */ +///////////////////////////////////////////////////////////////////////////// +// Name: imagalljpeg2000.h +// Purpose: wxImage JPEG 2000 family file format handler +// Author: G. Baruffa - based on imagjpeg.h, Vaclav Slavik +// RCS-ID: $Id: imagalljpeg2000.h,v 0.0 2008/01/31 11:22:00 VZ Exp $ +// Copyright: (c) Giuseppe Baruffa +// Licence: wxWindows licence +///////////////////////////////////////////////////////////////////////////// + +#ifndef _WX_IMAGJPEG2000_H_ +#define _WX_IMAGJPEG2000_H_ + +#include "wx/defs.h" + +//----------------------------------------------------------------------------- +// wxJPEG2000Handler +//----------------------------------------------------------------------------- + +#if wxUSE_LIBOPENJPEG + +#include "wx/image.h" +#include "libopenjpeg/openjpeg.h" +#include "codec/index.h" + +#define wxBITMAP_TYPE_JPEG2000 50 + +class WXDLLEXPORT wxJPEG2000Handler: public wxImageHandler +{ +public: + inline wxJPEG2000Handler() + { + m_name = wxT("JPEG 2000 family file format"); + m_extension = wxT("mj2"); + m_type = wxBITMAP_TYPE_JPEG2000; + m_mime = wxT("image/mj2"); + + /* decoding */ + 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 + + /* encoding */ + m_subsampling = wxT("1,1"); + m_origin = wxT("0,0"); + m_rates = wxT("20,10,5"); + m_quality = wxT("30,35,40"); + m_enablequality = false; + m_multicomp = false; + m_irreversible = false; + m_resolutions = 6; + m_progression = 0; + m_cbsize = wxT("32,32"); + m_prsize = wxT("[128,128],[128,128]"); + m_tsize = wxT(""); + m_torigin = wxT("0,0"); + /*m_progression + m_resilience*/ + m_enablesop = false; + m_enableeph = false; + m_enablereset = false; + m_enablesegmark = false; + m_enablevsc = false; + m_enablerestart = false; + m_enableerterm = false; + m_enablebypass = false; + /*m_roicompo + m_roiup + m_indexfname*/ + m_enableidx = false; + m_index = wxT("index.txt"); + m_enablepoc = false; + m_poc = wxT("T1=0,0,1,5,3,CPRL/T1=5,0,1,6,3,CPRL"); + m_enablecomm = true; + +#if defined __WXMSW__ + m_comment = wxT("Created by OPJViewer Win32 - OpenJPEG version "); +#elif defined __WXGTK__ + m_comment = wxT("Created by OPJViewer Lin32 - OpenJPEG version "); +#else + m_comment = wxT("Created by OPJViewer - OpenJPEG version "); +#endif + +#ifdef USE_JPWL + m_comment += wxString::Format(wxT("%s with JPWL"), (char *) opj_version()); +#else + m_comment += wxString::Format(wxT("%s"), (char *) opj_version()); +#endif + + } + + // decoding engine parameters + int m_reducefactor, m_qualitylayers, m_components, m_framenum; +#ifdef USE_JPWL + bool m_enablejpwl; + int m_expcomps, m_maxtiles; +#endif // USE_JPWL + + // encoding engine parameters + wxString m_subsampling; + wxString m_origin; + wxString m_rates; + wxString m_quality; + bool m_enablequality; + bool m_multicomp; + bool m_irreversible; + int m_resolutions; + int m_progression; + wxString m_cbsize; + wxString m_prsize; + wxString m_tsize; + wxString m_torigin; + /*m_progression + m_resilience*/ + bool m_enablesop; + bool m_enableeph; + bool m_enablebypass; + bool m_enableerterm; + bool m_enablerestart; + bool m_enablereset; + bool m_enablesegmark; + bool m_enablevsc; + /*m_roicompo + m_roiup + m_indexfname*/ + bool m_enableidx; + wxString m_index; + bool m_enablecomm; + wxString m_comment; + bool m_enablepoc; + wxString m_poc; + +#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); +protected: + virtual bool DoCanRead(wxInputStream& stream); +#endif + +private: + OPJ_PROG_ORDER give_progression(char progression[4]); + DECLARE_DYNAMIC_CLASS(wxJPEG2000Handler) +}; + +#endif // wxUSE_LIBOPENJPEG + +#endif // _WX_IMAGJPEG2000_H_ + diff --git a/applications/OPJViewer/source/imagmxf.cpp b/applications/OPJViewer/source/imagmxf.cpp index 99d0b939..ccfa9f9f 100644 --- a/applications/OPJViewer/source/imagmxf.cpp +++ b/applications/OPJViewer/source/imagmxf.cpp @@ -1,502 +1,502 @@ -/* - * Copyright (c) 2007, Digital Signal Processing Laboratory, Università degli studi di Perugia (UPG), Italy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are 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. - */ -///////////////////////////////////////////////////////////////////////////// -// Name: imagmxf.cpp -// Purpose: wxImage MXF (Material eXchange Format) JPEG 2000 file format handler -// Author: Giuseppe Baruffa - based on imagjpeg.cpp, Vaclav Slavik -// RCS-ID: $Id: imagmxf.cpp,v 0.00 2007/11/19 17:00:00 MW Exp $ -// Copyright: (c) Giuseppe Baruffa -// Licence: wxWindows licence -///////////////////////////////////////////////////////////////////////////// - -#ifdef USE_MXF - -#include "mxflib/mxflib.h" -using namespace mxflib; - -namespace -{ - //! Structure holding information about the essence in each body stream - struct EssenceInfo - { - UMIDPtr PackageID; - PackagePtr Package; - MDObjectPtr Descriptor; - }; - //! Map of EssenceInfo structures indexed by BodySID - typedef std::map EssenceInfoMap; - - //! The map of essence info for this file - EssenceInfoMap EssenceLookup; -}; - -//! Build an EssenceInfoMap for the essence in a given file -/*! \return True if al OK, else false - */ -bool BuildEssenceInfo(MXFFilePtr &File, EssenceInfoMap &EssenceLookup); - -// For compilers that support precompilation, includes "wx.h". -#include "wx/wxprec.h" - -#ifdef __BORLANDC__ - #pragma hdrstop -#endif - -#if wxUSE_IMAGE && wxUSE_LIBOPENJPEG - -#include "imagmxf.h" - -#ifndef WX_PRECOMP - #include "wx/log.h" - #include "wx/app.h" - #include "wx/intl.h" - #include "wx/bitmap.h" - #include "wx/module.h" -#endif - - -#include "libopenjpeg/openjpeg.h" - - -#include "wx/filefn.h" -#include "wx/wfstream.h" - -// ---------------------------------------------------------------------------- -// types -// ---------------------------------------------------------------------------- - - -//----------------------------------------------------------------------------- -// wxMXFHandler -//----------------------------------------------------------------------------- - -IMPLEMENT_DYNAMIC_CLASS(wxMXFHandler,wxImageHandler) - -#if wxUSE_STREAMS - -#include -#define MAX_MESSAGE_LEN 200 - -//------------- MXF Manager - -// Debug and error messages - -//! Display a warning message -void mxflib::warning(const char *Fmt, ...) -{ - char msg[MAX_MESSAGE_LEN]; - va_list args; - - va_start(args, Fmt); - _vsnprintf(msg, MAX_MESSAGE_LEN, Fmt, args); - va_end(args); - - int message_len = strlen(msg) - 1; - if (msg[message_len] != '\n') - message_len = MAX_MESSAGE_LEN; -#ifndef __WXGTK__ - wxMutexGuiEnter(); -#endif /* __WXGTK__ */ - wxLogMessage(wxT("[WARNING_MXF] %.*s"), message_len, msg); -#ifndef __WXGTK__ - wxMutexGuiLeave(); -#endif /* __WXGTK__ */ -} - -//! Display an error message -void mxflib::error(const char *Fmt, ...) -{ - char msg[MAX_MESSAGE_LEN]; - va_list args; - - va_start(args, Fmt); - _vsnprintf(msg, MAX_MESSAGE_LEN, Fmt, args); - va_end(args); - - int message_len = strlen(msg) - 1; - if (msg[message_len] != '\n') - message_len = MAX_MESSAGE_LEN; -#ifndef __WXGTK__ - wxMutexGuiEnter(); -#endif /* __WXGTK__ */ - wxLogMessage(wxT("[ERROR_MXF] %.*s"), message_len, msg); -#ifndef __WXGTK__ - wxMutexGuiLeave(); -#endif /* __WXGTK__ */ -} - -//! Display an error message -void mxflib::debug(const char *Fmt, ...) -{ - char msg[MAX_MESSAGE_LEN]; - va_list args; - - va_start(args, Fmt); - _vsnprintf(msg, MAX_MESSAGE_LEN, Fmt, args); - va_end(args); - - int message_len = strlen(msg) - 1; - if (msg[message_len] != '\n') - message_len = MAX_MESSAGE_LEN; -#ifndef __WXGTK__ - wxMutexGuiEnter(); -#endif /* __WXGTK__ */ - wxLogMessage(wxT("[DEBUG_MXF] %.*s"), message_len, msg); -#ifndef __WXGTK__ - wxMutexGuiLeave(); -#endif /* __WXGTK__ */ -} - - - -//------------- JPEG 2000 Data Source Manager - -#define J2K_CFMT 0 -#define JP2_CFMT 1 -#define JPT_CFMT 2 -#define MJ2_CFMT 3 -#define PXM_DFMT 0 -#define PGX_DFMT 1 -#define BMP_DFMT 2 -#define YUV_DFMT 3 - -/* sample error callback expecting a FILE* client object */ -void mxf_error_callback(const char *msg, void *client_data) { - int message_len = strlen(msg) - 1; - if (msg[message_len] != '\n') - message_len = MAX_MESSAGE_LEN; -#ifndef __WXGTK__ - wxMutexGuiEnter(); -#endif /* __WXGTK__ */ - wxLogMessage(wxT("[ERROR] %.*s"), message_len, msg); -#ifndef __WXGTK__ - wxMutexGuiLeave(); -#endif /* __WXGTK__ */ -} - -/* sample warning callback expecting a FILE* client object */ -void mxf_warning_callback(const char *msg, void *client_data) { - int message_len = strlen(msg) - 1; - if (msg[message_len] != '\n') - message_len = MAX_MESSAGE_LEN; -#ifndef __WXGTK__ - wxMutexGuiEnter(); -#endif /* __WXGTK__ */ - wxLogMessage(wxT("[WARNING] %.*s"), message_len, msg); -#ifndef __WXGTK__ - wxMutexGuiLeave(); -#endif /* __WXGTK__ */ -} - -/* sample debug callback expecting no client object */ -void mxf_info_callback(const char *msg, void *client_data) { - int message_len = strlen(msg) - 1; - if (msg[message_len] != '\n') - message_len = MAX_MESSAGE_LEN; -#ifndef __WXGTK__ - wxMutexGuiEnter(); -#endif /* __WXGTK__ */ - wxLogMessage(wxT("[INFO] %.*s"), message_len, msg); -#ifndef __WXGTK__ - wxMutexGuiLeave(); -#endif /* __WXGTK__ */ -} - - -///////////////////////////////////////////////// -///////////////////////////////////////////////// - -// load the mxf file format -bool wxMXFHandler::LoadFile(wxImage *image, wxInputStream& stream, bool verbose, int index) -{ - opj_dparameters_t parameters; /* decompression parameters */ - opj_event_mgr_t event_mgr; /* event manager */ - opj_image_t *opjimage = NULL; - unsigned char *src = NULL; - unsigned char *ptr; - int file_length, j2k_point, j2k_len; - opj_codestream_info_t cstr_info; /* Codestream information structure */ - - // simply display the version of the library - wxLogMessage(wxT("Version of MXF: %s "), wxString::FromAscii(LibraryVersion().c_str())); - //wxLogMessage(wxT("MXF file name: %s"), m_filename.GetFullPath()); - - // open MXF file - MXFFilePtr TestFile = new MXFFile; - if (! TestFile->Open(m_filename.GetFullPath().c_str(), true)) - { - wxLogError(wxT("Could not find %s"), m_filename.GetFullPath().c_str()); - return false; - } else - wxLogMessage(wxT("Found %s"), m_filename.GetFullPath().c_str()); - - // Get the size - TestFile->SeekEnd(); - wxLogMessage(wxT("Size is %d bytes"), TestFile->Tell()); - TestFile->Seek(0); - - // essence information - //BuildEssenceInfo(TestFile, EssenceLookup); - - // close MXF file - TestFile->Close(); - - return false; - - // destroy the image - image->Destroy(); - - /* handle to a decompressor */ - opj_dinfo_t* dinfo = NULL; - opj_cio_t *cio = NULL; - - /* configure the event callbacks (not required) */ - memset(&event_mgr, 0, sizeof(opj_event_mgr_t)); - event_mgr.error_handler = mxf_error_callback; - event_mgr.warning_handler = mxf_warning_callback; - event_mgr.info_handler = mxf_info_callback; - - /* set decoding parameters to default values */ - opj_set_default_decoder_parameters(¶meters); - - /* prepare parameters */ - strncpy(parameters.infile, "", sizeof(parameters.infile)-1); - 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 = 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_J2K); - - /* find length of the stream */ - stream.SeekI(0, wxFromEnd); - file_length = (int) stream.TellI(); - - /* search for the m_framenum codestream position and length */ - //jp2c_point = searchjp2c(stream, file_length, m_framenum); - //jp2c_len = searchjp2c(stream, file_length, m_framenum); - j2k_point = 0; - j2k_len = 10; - - // malloc memory source - src = (unsigned char *) malloc(j2k_len); - - // copy the jp2c - stream.SeekI(j2k_point, wxFromStart); - stream.Read(src, j2k_len); - - /* catch events using our callbacks and give a local context */ - opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, stderr); - - /* setup the decoder decoding parameters using user parameters */ - opj_setup_decoder(dinfo, ¶meters); - - /* open a byte stream */ - cio = opj_cio_open((opj_common_ptr)dinfo, src, j2k_len); - - /* decode the stream and fill the image structure */ - opjimage = opj_decode_with_info(dinfo, cio, &cstr_info); - if (!opjimage) { - wxMutexGuiEnter(); - wxLogError(wxT("MXF: failed to decode image!")); - wxMutexGuiLeave(); - opj_destroy_decompress(dinfo); - opj_cio_close(cio); - free(src); - return false; - } - - /* close the byte stream */ - opj_cio_close(cio); - - /* common rendering method */ -#include "imagjpeg2000.cpp" - - wxMutexGuiEnter(); - wxLogMessage(wxT("MXF: image loaded.")); - wxMutexGuiLeave(); - - /* close openjpeg structs */ - opj_destroy_decompress(dinfo); - opj_image_destroy(opjimage); - free(src); - - if (!image->Ok()) - return false; - else - return true; - -} - -// save the mxf file format -bool wxMXFHandler::SaveFile( wxImage *image, wxOutputStream& stream, bool verbose ) -{ - wxLogError(wxT("MXF: Couldn't save movie -> not implemented.")); - return false; -} - -#ifdef __VISUALC__ - #pragma warning(default:4611) -#endif /* VC++ */ - -// recognize the MXF JPEG 2000 starting box -bool wxMXFHandler::DoCanRead( wxInputStream& stream ) -{ - unsigned char hdr[4]; - - if ( !stream.Read(hdr, WXSIZEOF(hdr)) ) - return false; - - return (hdr[0] == 0x06 && - hdr[1] == 0x0E && - hdr[2] == 0x2B && - hdr[3] == 0x34); -} - -//! Build an EssenceInfoMap for the essence in a given file -/*! \return True if al OK, else false - */ -bool BuildEssenceInfo(MXFFilePtr &File, EssenceInfoMap &EssenceLookup) -{ - // Empty any old data - EssenceLookup.clear(); - - // Get the master metadata set (or the header if we must) - PartitionPtr MasterPartition = File->ReadMasterPartition(); - if(!MasterPartition) - { - File->Seek(0); - MasterPartition = File->ReadPartition(); - warning("File %s does not contain a cloased copy of header metadata - using the open copy in the file header\n", File->Name.c_str()); - } - - if(!MasterPartition) - { - error("Could not read header metadata from file %s\n", File->Name.c_str()); - return false; - } - - // Read and parse the metadata - MasterPartition->ReadMetadata(); - MetadataPtr HMeta = MasterPartition->ParseMetadata(); - - if(!HMeta) - { - error("Could not read header metadata from file %s\n", File->Name.c_str()); - return false; - } - - /* Scan the Essence container data sets to get PackageID to BodySID mapping */ - MDObjectPtr ECDSet = HMeta[ContentStorage_UL]; - if(ECDSet) ECDSet = ECDSet->GetLink(); - if(ECDSet) ECDSet = ECDSet[EssenceContainerDataBatch_UL]; - if(!ECDSet) - { - error("Header metadata in file %s does not contain an EssenceContainerData set\n", File->Name.c_str()); - return false; - } - - MDObject::iterator it = ECDSet->begin(); - while(it != ECDSet->end()) - { - MDObjectPtr ThisECDSet = (*it).second->GetLink(); - MDObjectPtr PackageID; - if(ThisECDSet) PackageID = ThisECDSet->Child(LinkedPackageUID_UL); - if(PackageID) - { - EssenceInfo NewEI; - NewEI.PackageID = new UMID(PackageID->PutData()->Data); - - // Inset the basic essence info - but not if this is external essence (BodySID == 0) - UInt32 BodySID = ThisECDSet->GetUInt(BodySID_UL); - if(BodySID) EssenceLookup[BodySID] = NewEI; - } - it++; - } - - /* Now find the other items for the essence lookup map */ - if(EssenceLookup.size()) - { - PackageList::iterator it = HMeta->Packages.begin(); - while(it != HMeta->Packages.end()) - { - // Only Source Packages are of interest - if((*it)->IsA(SourcePackage_UL)) - { - MDObjectPtr Descriptor = (*it)->Child(Descriptor_UL); - if(Descriptor) Descriptor = Descriptor->GetLink(); - - if(Descriptor) - { - MDObjectPtr PackageID = (*it)->Child(PackageUID_UL); - if(PackageID) - { - UMIDPtr TheID = new UMID(PackageID->PutData()->Data); - - /* Now do a lookup in the essence lookup map (it will need to be done the long way here */ - EssenceInfoMap::iterator EL_it = EssenceLookup.begin(); - while(EL_it != EssenceLookup.end()) - { - if((*((*EL_it).second.PackageID)) == (*TheID)) - { - // If found, set the missing items and stop searching - (*EL_it).second.Package = (*it); - (*EL_it).second.Descriptor = Descriptor; - break; - } - EL_it++; - } - } - } - } - - it++; - } - } - - return true; -} - - -#endif // wxUSE_STREAMS - -#endif // wxUSE_LIBOPENJPEG - -#endif // USE_MXF - +/* + * Copyright (c) 2007, Digital Signal Processing Laboratory, Università degli studi di Perugia (UPG), Italy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are 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. + */ +///////////////////////////////////////////////////////////////////////////// +// Name: imagmxf.cpp +// Purpose: wxImage MXF (Material eXchange Format) JPEG 2000 file format handler +// Author: Giuseppe Baruffa - based on imagjpeg.cpp, Vaclav Slavik +// RCS-ID: $Id: imagmxf.cpp,v 0.00 2007/11/19 17:00:00 MW Exp $ +// Copyright: (c) Giuseppe Baruffa +// Licence: wxWindows licence +///////////////////////////////////////////////////////////////////////////// + +#ifdef USE_MXF + +#include "mxflib/mxflib.h" +using namespace mxflib; + +namespace +{ + //! Structure holding information about the essence in each body stream + struct EssenceInfo + { + UMIDPtr PackageID; + PackagePtr Package; + MDObjectPtr Descriptor; + }; + //! Map of EssenceInfo structures indexed by BodySID + typedef std::map EssenceInfoMap; + + //! The map of essence info for this file + EssenceInfoMap EssenceLookup; +}; + +//! Build an EssenceInfoMap for the essence in a given file +/*! \return True if al OK, else false + */ +bool BuildEssenceInfo(MXFFilePtr &File, EssenceInfoMap &EssenceLookup); + +// For compilers that support precompilation, includes "wx.h". +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ + #pragma hdrstop +#endif + +#if wxUSE_IMAGE && wxUSE_LIBOPENJPEG + +#include "imagmxf.h" + +#ifndef WX_PRECOMP + #include "wx/log.h" + #include "wx/app.h" + #include "wx/intl.h" + #include "wx/bitmap.h" + #include "wx/module.h" +#endif + + +#include "libopenjpeg/openjpeg.h" + + +#include "wx/filefn.h" +#include "wx/wfstream.h" + +// ---------------------------------------------------------------------------- +// types +// ---------------------------------------------------------------------------- + + +//----------------------------------------------------------------------------- +// wxMXFHandler +//----------------------------------------------------------------------------- + +IMPLEMENT_DYNAMIC_CLASS(wxMXFHandler,wxImageHandler) + +#if wxUSE_STREAMS + +#include +#define MAX_MESSAGE_LEN 200 + +//------------- MXF Manager + +// Debug and error messages + +//! Display a warning message +void mxflib::warning(const char *Fmt, ...) +{ + char msg[MAX_MESSAGE_LEN]; + va_list args; + + va_start(args, Fmt); + _vsnprintf(msg, MAX_MESSAGE_LEN, Fmt, args); + va_end(args); + + int message_len = strlen(msg) - 1; + if (msg[message_len] != '\n') + message_len = MAX_MESSAGE_LEN; +#ifndef __WXGTK__ + wxMutexGuiEnter(); +#endif /* __WXGTK__ */ + wxLogMessage(wxT("[WARNING_MXF] %.*s"), message_len, msg); +#ifndef __WXGTK__ + wxMutexGuiLeave(); +#endif /* __WXGTK__ */ +} + +//! Display an error message +void mxflib::error(const char *Fmt, ...) +{ + char msg[MAX_MESSAGE_LEN]; + va_list args; + + va_start(args, Fmt); + _vsnprintf(msg, MAX_MESSAGE_LEN, Fmt, args); + va_end(args); + + int message_len = strlen(msg) - 1; + if (msg[message_len] != '\n') + message_len = MAX_MESSAGE_LEN; +#ifndef __WXGTK__ + wxMutexGuiEnter(); +#endif /* __WXGTK__ */ + wxLogMessage(wxT("[ERROR_MXF] %.*s"), message_len, msg); +#ifndef __WXGTK__ + wxMutexGuiLeave(); +#endif /* __WXGTK__ */ +} + +//! Display an error message +void mxflib::debug(const char *Fmt, ...) +{ + char msg[MAX_MESSAGE_LEN]; + va_list args; + + va_start(args, Fmt); + _vsnprintf(msg, MAX_MESSAGE_LEN, Fmt, args); + va_end(args); + + int message_len = strlen(msg) - 1; + if (msg[message_len] != '\n') + message_len = MAX_MESSAGE_LEN; +#ifndef __WXGTK__ + wxMutexGuiEnter(); +#endif /* __WXGTK__ */ + wxLogMessage(wxT("[DEBUG_MXF] %.*s"), message_len, msg); +#ifndef __WXGTK__ + wxMutexGuiLeave(); +#endif /* __WXGTK__ */ +} + + + +//------------- JPEG 2000 Data Source Manager + +#define J2K_CFMT 0 +#define JP2_CFMT 1 +#define JPT_CFMT 2 +#define MJ2_CFMT 3 +#define PXM_DFMT 0 +#define PGX_DFMT 1 +#define BMP_DFMT 2 +#define YUV_DFMT 3 + +/* sample error callback expecting a FILE* client object */ +void mxf_error_callback(const char *msg, void *client_data) { + int message_len = strlen(msg) - 1; + if (msg[message_len] != '\n') + message_len = MAX_MESSAGE_LEN; +#ifndef __WXGTK__ + wxMutexGuiEnter(); +#endif /* __WXGTK__ */ + wxLogMessage(wxT("[ERROR] %.*s"), message_len, msg); +#ifndef __WXGTK__ + wxMutexGuiLeave(); +#endif /* __WXGTK__ */ +} + +/* sample warning callback expecting a FILE* client object */ +void mxf_warning_callback(const char *msg, void *client_data) { + int message_len = strlen(msg) - 1; + if (msg[message_len] != '\n') + message_len = MAX_MESSAGE_LEN; +#ifndef __WXGTK__ + wxMutexGuiEnter(); +#endif /* __WXGTK__ */ + wxLogMessage(wxT("[WARNING] %.*s"), message_len, msg); +#ifndef __WXGTK__ + wxMutexGuiLeave(); +#endif /* __WXGTK__ */ +} + +/* sample debug callback expecting no client object */ +void mxf_info_callback(const char *msg, void *client_data) { + int message_len = strlen(msg) - 1; + if (msg[message_len] != '\n') + message_len = MAX_MESSAGE_LEN; +#ifndef __WXGTK__ + wxMutexGuiEnter(); +#endif /* __WXGTK__ */ + wxLogMessage(wxT("[INFO] %.*s"), message_len, msg); +#ifndef __WXGTK__ + wxMutexGuiLeave(); +#endif /* __WXGTK__ */ +} + + +///////////////////////////////////////////////// +///////////////////////////////////////////////// + +// load the mxf file format +bool wxMXFHandler::LoadFile(wxImage *image, wxInputStream& stream, bool verbose, int index) +{ + opj_dparameters_t parameters; /* decompression parameters */ + opj_event_mgr_t event_mgr; /* event manager */ + opj_image_t *opjimage = NULL; + unsigned char *src = NULL; + unsigned char *ptr; + int file_length, j2k_point, j2k_len; + opj_codestream_info_t cstr_info; /* Codestream information structure */ + + // simply display the version of the library + wxLogMessage(wxT("Version of MXF: %s "), wxString::FromAscii(LibraryVersion().c_str())); + //wxLogMessage(wxT("MXF file name: %s"), m_filename.GetFullPath()); + + // open MXF file + MXFFilePtr TestFile = new MXFFile; + if (! TestFile->Open(m_filename.GetFullPath().c_str(), true)) + { + wxLogError(wxT("Could not find %s"), m_filename.GetFullPath().c_str()); + return false; + } else + wxLogMessage(wxT("Found %s"), m_filename.GetFullPath().c_str()); + + // Get the size + TestFile->SeekEnd(); + wxLogMessage(wxT("Size is %d bytes"), TestFile->Tell()); + TestFile->Seek(0); + + // essence information + //BuildEssenceInfo(TestFile, EssenceLookup); + + // close MXF file + TestFile->Close(); + + return false; + + // destroy the image + image->Destroy(); + + /* handle to a decompressor */ + opj_dinfo_t* dinfo = NULL; + opj_cio_t *cio = NULL; + + /* configure the event callbacks (not required) */ + memset(&event_mgr, 0, sizeof(opj_event_mgr_t)); + event_mgr.error_handler = mxf_error_callback; + event_mgr.warning_handler = mxf_warning_callback; + event_mgr.info_handler = mxf_info_callback; + + /* set decoding parameters to default values */ + opj_set_default_decoder_parameters(¶meters); + + /* prepare parameters */ + strncpy(parameters.infile, "", sizeof(parameters.infile)-1); + 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 = 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_J2K); + + /* find length of the stream */ + stream.SeekI(0, wxFromEnd); + file_length = (int) stream.TellI(); + + /* search for the m_framenum codestream position and length */ + //jp2c_point = searchjp2c(stream, file_length, m_framenum); + //jp2c_len = searchjp2c(stream, file_length, m_framenum); + j2k_point = 0; + j2k_len = 10; + + // malloc memory source + src = (unsigned char *) malloc(j2k_len); + + // copy the jp2c + stream.SeekI(j2k_point, wxFromStart); + stream.Read(src, j2k_len); + + /* catch events using our callbacks and give a local context */ + opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, stderr); + + /* setup the decoder decoding parameters using user parameters */ + opj_setup_decoder(dinfo, ¶meters); + + /* open a byte stream */ + cio = opj_cio_open((opj_common_ptr)dinfo, src, j2k_len); + + /* decode the stream and fill the image structure */ + opjimage = opj_decode_with_info(dinfo, cio, &cstr_info); + if (!opjimage) { + wxMutexGuiEnter(); + wxLogError(wxT("MXF: failed to decode image!")); + wxMutexGuiLeave(); + opj_destroy_decompress(dinfo); + opj_cio_close(cio); + free(src); + return false; + } + + /* close the byte stream */ + opj_cio_close(cio); + + /* common rendering method */ +#include "imagjpeg2000.cpp" + + wxMutexGuiEnter(); + wxLogMessage(wxT("MXF: image loaded.")); + wxMutexGuiLeave(); + + /* close openjpeg structs */ + opj_destroy_decompress(dinfo); + opj_image_destroy(opjimage); + free(src); + + if (!image->Ok()) + return false; + else + return true; + +} + +// save the mxf file format +bool wxMXFHandler::SaveFile( wxImage *image, wxOutputStream& stream, bool verbose ) +{ + wxLogError(wxT("MXF: Couldn't save movie -> not implemented.")); + return false; +} + +#ifdef __VISUALC__ + #pragma warning(default:4611) +#endif /* VC++ */ + +// recognize the MXF JPEG 2000 starting box +bool wxMXFHandler::DoCanRead( wxInputStream& stream ) +{ + unsigned char hdr[4]; + + if ( !stream.Read(hdr, WXSIZEOF(hdr)) ) + return false; + + return (hdr[0] == 0x06 && + hdr[1] == 0x0E && + hdr[2] == 0x2B && + hdr[3] == 0x34); +} + +//! Build an EssenceInfoMap for the essence in a given file +/*! \return True if al OK, else false + */ +bool BuildEssenceInfo(MXFFilePtr &File, EssenceInfoMap &EssenceLookup) +{ + // Empty any old data + EssenceLookup.clear(); + + // Get the master metadata set (or the header if we must) + PartitionPtr MasterPartition = File->ReadMasterPartition(); + if(!MasterPartition) + { + File->Seek(0); + MasterPartition = File->ReadPartition(); + warning("File %s does not contain a cloased copy of header metadata - using the open copy in the file header\n", File->Name.c_str()); + } + + if(!MasterPartition) + { + error("Could not read header metadata from file %s\n", File->Name.c_str()); + return false; + } + + // Read and parse the metadata + MasterPartition->ReadMetadata(); + MetadataPtr HMeta = MasterPartition->ParseMetadata(); + + if(!HMeta) + { + error("Could not read header metadata from file %s\n", File->Name.c_str()); + return false; + } + + /* Scan the Essence container data sets to get PackageID to BodySID mapping */ + MDObjectPtr ECDSet = HMeta[ContentStorage_UL]; + if(ECDSet) ECDSet = ECDSet->GetLink(); + if(ECDSet) ECDSet = ECDSet[EssenceContainerDataBatch_UL]; + if(!ECDSet) + { + error("Header metadata in file %s does not contain an EssenceContainerData set\n", File->Name.c_str()); + return false; + } + + MDObject::iterator it = ECDSet->begin(); + while(it != ECDSet->end()) + { + MDObjectPtr ThisECDSet = (*it).second->GetLink(); + MDObjectPtr PackageID; + if(ThisECDSet) PackageID = ThisECDSet->Child(LinkedPackageUID_UL); + if(PackageID) + { + EssenceInfo NewEI; + NewEI.PackageID = new UMID(PackageID->PutData()->Data); + + // Inset the basic essence info - but not if this is external essence (BodySID == 0) + UInt32 BodySID = ThisECDSet->GetUInt(BodySID_UL); + if(BodySID) EssenceLookup[BodySID] = NewEI; + } + it++; + } + + /* Now find the other items for the essence lookup map */ + if(EssenceLookup.size()) + { + PackageList::iterator it = HMeta->Packages.begin(); + while(it != HMeta->Packages.end()) + { + // Only Source Packages are of interest + if((*it)->IsA(SourcePackage_UL)) + { + MDObjectPtr Descriptor = (*it)->Child(Descriptor_UL); + if(Descriptor) Descriptor = Descriptor->GetLink(); + + if(Descriptor) + { + MDObjectPtr PackageID = (*it)->Child(PackageUID_UL); + if(PackageID) + { + UMIDPtr TheID = new UMID(PackageID->PutData()->Data); + + /* Now do a lookup in the essence lookup map (it will need to be done the long way here */ + EssenceInfoMap::iterator EL_it = EssenceLookup.begin(); + while(EL_it != EssenceLookup.end()) + { + if((*((*EL_it).second.PackageID)) == (*TheID)) + { + // If found, set the missing items and stop searching + (*EL_it).second.Package = (*it); + (*EL_it).second.Descriptor = Descriptor; + break; + } + EL_it++; + } + } + } + } + + it++; + } + } + + return true; +} + + +#endif // wxUSE_STREAMS + +#endif // wxUSE_LIBOPENJPEG + +#endif // USE_MXF + diff --git a/applications/OPJViewer/source/imagmxf.h b/applications/OPJViewer/source/imagmxf.h index c87a4cb4..2f287bfd 100644 --- a/applications/OPJViewer/source/imagmxf.h +++ b/applications/OPJViewer/source/imagmxf.h @@ -1,99 +1,99 @@ -/* - * Copyright (c) 2007, Digital Signal Processing Laboratory, Università degli studi di Perugia (UPG), Italy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are 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. - */ -///////////////////////////////////////////////////////////////////////////// -// Name: imagmxf.h -// Purpose: wxImage MXF (Material eXchange Format) JPEG 2000 file format handler -// Author: G. Baruffa - based on imagjpeg.h, Vaclav Slavik -// RCS-ID: $Id: imagmj2.h,v 0.0 2007/11/19 17:00:00 VZ Exp $ -// Copyright: (c) Giuseppe Baruffa -// Licence: wxWindows licence -///////////////////////////////////////////////////////////////////////////// - -#ifndef _WX_IMAGMXF_H_ -#define _WX_IMAGMXF_H_ - -#ifdef USE_MXF - -#include "wx/defs.h" -#include "wx/filename.h" - -//----------------------------------------------------------------------------- -// wxMXFHandler -//----------------------------------------------------------------------------- - -#if wxUSE_LIBOPENJPEG - -#include "wx/image.h" -#include "libopenjpeg/openjpeg.h" - -#define wxBITMAP_TYPE_MXF 51 - -class WXDLLEXPORT wxMXFHandler: public wxImageHandler -{ -public: - inline wxMXFHandler() - { - m_name = wxT("MXF JPEG 2000 file format"); - m_extension = wxT("mxf"); - m_type = wxBITMAP_TYPE_MXF; - m_mime = wxT("image/mxf"); - - m_reducefactor = 0; - m_qualitylayers = 0; - m_components = 0; - m_filename = wxT(""); -#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, m_framenum; - wxFileName m_filename; -#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 ); -protected: - virtual bool DoCanRead( wxInputStream& stream ); -#endif - -private: - DECLARE_DYNAMIC_CLASS(wxMXFHandler) -}; - -#endif // wxUSE_LIBOPENJPEG - -#endif // USE_MXF - -#endif // _WX_IMAGMXF_H_ - +/* + * Copyright (c) 2007, Digital Signal Processing Laboratory, Università degli studi di Perugia (UPG), Italy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are 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. + */ +///////////////////////////////////////////////////////////////////////////// +// Name: imagmxf.h +// Purpose: wxImage MXF (Material eXchange Format) JPEG 2000 file format handler +// Author: G. Baruffa - based on imagjpeg.h, Vaclav Slavik +// RCS-ID: $Id: imagmj2.h,v 0.0 2007/11/19 17:00:00 VZ Exp $ +// Copyright: (c) Giuseppe Baruffa +// Licence: wxWindows licence +///////////////////////////////////////////////////////////////////////////// + +#ifndef _WX_IMAGMXF_H_ +#define _WX_IMAGMXF_H_ + +#ifdef USE_MXF + +#include "wx/defs.h" +#include "wx/filename.h" + +//----------------------------------------------------------------------------- +// wxMXFHandler +//----------------------------------------------------------------------------- + +#if wxUSE_LIBOPENJPEG + +#include "wx/image.h" +#include "libopenjpeg/openjpeg.h" + +#define wxBITMAP_TYPE_MXF 51 + +class WXDLLEXPORT wxMXFHandler: public wxImageHandler +{ +public: + inline wxMXFHandler() + { + m_name = wxT("MXF JPEG 2000 file format"); + m_extension = wxT("mxf"); + m_type = wxBITMAP_TYPE_MXF; + m_mime = wxT("image/mxf"); + + m_reducefactor = 0; + m_qualitylayers = 0; + m_components = 0; + m_filename = wxT(""); +#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, m_framenum; + wxFileName m_filename; +#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 ); +protected: + virtual bool DoCanRead( wxInputStream& stream ); +#endif + +private: + DECLARE_DYNAMIC_CLASS(wxMXFHandler) +}; + +#endif // wxUSE_LIBOPENJPEG + +#endif // USE_MXF + +#endif // _WX_IMAGMXF_H_ + diff --git a/applications/OPJViewer/source/license.txt b/applications/OPJViewer/source/license.txt index 81d6b349..6409db44 100644 --- a/applications/OPJViewer/source/license.txt +++ b/applications/OPJViewer/source/license.txt @@ -1,14 +1,14 @@ -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 -Copyright (c) 2007, Digital Signal Processing Laboratory, Università degli studi di Perugia (UPG), Italy -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. - +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 +Copyright (c) 2007, Digital Signal Processing Laboratory, Università degli studi di Perugia (UPG), Italy +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/applications/OPJViewer/source/readmeafter.txt b/applications/OPJViewer/source/readmeafter.txt index d5e8fb9a..87c122be 100644 --- a/applications/OPJViewer/source/readmeafter.txt +++ b/applications/OPJViewer/source/readmeafter.txt @@ -1,34 +1,34 @@ -This viewer is conceived to open and display information and image content of J2K, JP2, -and MJ2 files. -The viewer application interface is divided into three main panels: -- a browsing pane; -- a viewing pane; -- a log/peek pane. - -The browsing pane will present the markers or boxes hierarchy, with position (byte number where marker/box starts and stops) and length information (i.e., inner length as signalled by marker/box and total length, with marker/box sign included), in the following form: - -filename -| -|_ #000: Marker/Box short name (Hex code) -| | -| |_ *** Marker/Box long name *** -| |_ startbyte > stopbyte, inner_length + marker/box sign length (total length) -| |_ Additional info, depending on the marker/box type -| |_ ... -| -|_ #001: Marker/Box short name (Hex code) -| | -| |_ ... -| -... - - -The viewing pane will display the decoded image contained in the JPEG 2000 file. -It should display correctly images as large as 4000x2000, provided that a couple of GB of RAM are available. Nothing is known about the display of larger sizes: let us know if you manage to get it working. - - -The log/peek pane is shared among two different subpanels: - -- the log panel will report a lot of debugging info coming out from the wx GUI as well as from the openjpeg library -- the peek pane tries to give a peek on the codestream/file portion which is currently selected in the browsing pane. It shows both hex and ascii values corresponding to the marker/box section. - +This viewer is conceived to open and display information and image content of J2K, JP2, +and MJ2 files. +The viewer application interface is divided into three main panels: +- a browsing pane; +- a viewing pane; +- a log/peek pane. + +The browsing pane will present the markers or boxes hierarchy, with position (byte number where marker/box starts and stops) and length information (i.e., inner length as signalled by marker/box and total length, with marker/box sign included), in the following form: + +filename +| +|_ #000: Marker/Box short name (Hex code) +| | +| |_ *** Marker/Box long name *** +| |_ startbyte > stopbyte, inner_length + marker/box sign length (total length) +| |_ Additional info, depending on the marker/box type +| |_ ... +| +|_ #001: Marker/Box short name (Hex code) +| | +| |_ ... +| +... + + +The viewing pane will display the decoded image contained in the JPEG 2000 file. +It should display correctly images as large as 4000x2000, provided that a couple of GB of RAM are available. Nothing is known about the display of larger sizes: let us know if you manage to get it working. + + +The log/peek pane is shared among two different subpanels: + +- the log panel will report a lot of debugging info coming out from the wx GUI as well as from the openjpeg library +- the peek pane tries to give a peek on the codestream/file portion which is currently selected in the browsing pane. It shows both hex and ascii values corresponding to the marker/box section. + diff --git a/applications/OPJViewer/source/readmebefore.txt b/applications/OPJViewer/source/readmebefore.txt index c5e1ed87..a59b0e87 100644 --- a/applications/OPJViewer/source/readmebefore.txt +++ b/applications/OPJViewer/source/readmebefore.txt @@ -1,11 +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 ? -=============================== +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/applications/OPJViewer/source/wxj2kparser.cpp b/applications/OPJViewer/source/wxj2kparser.cpp index eb48abeb..284c568a 100644 --- a/applications/OPJViewer/source/wxj2kparser.cpp +++ b/applications/OPJViewer/source/wxj2kparser.cpp @@ -1,1465 +1,1465 @@ -/* - * Copyright (c) 2007, Digital Signal Processing Laboratory, Università degli studi di Perugia (UPG), Italy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are 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. - */ -#include "OPJViewer.h" - -/* From little endian to big endian, 2 bytes */ -#define BYTE_SWAP2(X) ((X & 0x00FF) << 8) | ((X & 0xFF00) >> 8) -#define BYTE_SWAP4(X) ((X & 0x000000FF) << 24) | ((X & 0x0000FF00) << 8) | ((X & 0x00FF0000) >> 8) | ((X & 0xFF000000) >> 24) - -/* From codestream to int values */ -#define STREAM_TO_UINT32(C, P) (((unsigned long int) (C)[(P) + 0] << 24) + \ - ((unsigned long int) (C)[(P) + 1] << 16) + \ - ((unsigned long int) (C)[(P) + 2] << 8) + \ - ((unsigned long int) (C)[(P) + 3] << 0)) - -#define STREAM_TO_UINT16(C, P) (((unsigned long int) (C)[(P) + 0] << 8) + \ - ((unsigned long int) (C)[(P) + 1] << 0)) - - -/* Markers values */ -#define J2KMARK_NUM 24 -enum { - SOC_VAL = 0xFF4F, - SOT_VAL = 0xFF90, - SOD_VAL = 0xFF93, - EOC_VAL = 0xFFD9, - SIZ_VAL = 0xFF51, - COD_VAL = 0xFF52, - COC_VAL = 0xFF53, - RGN_VAL = 0xFF5E, - QCD_VAL = 0xFF5C, - QCC_VAL = 0xFF5D, - POD_VAL = 0xFF5F, - TLM_VAL = 0xFF55, - PLM_VAL = 0xFF57, - PLT_VAL = 0xFF58, - PPM_VAL = 0xFF60, - PPT_VAL = 0xFF61, - SOP_VAL = 0xFF91, - EPH_VAL = 0xFF92, - COM_VAL = 0xFF64 -#ifdef USE_JPWL - , EPB_VAL = 0xFF66, - ESD_VAL = 0xFF67, - EPC_VAL = 0xFF68, - RED_VAL = 0xFF69 - /*, EPB_VAL = 0xFF96, - ESD_VAL = 0xFF98, - EPC_VAL = 0xFF97, - RED_VAL = 0xFF99*/ -#endif // USE_JPWL -#ifdef USE_JPSEC - , SEC_VAL = 0xFF65 -#endif // USE_JPSEC -}; - -// All the markers in one vector -unsigned short int marker_val[] = { - SOC_VAL, SOT_VAL, SOD_VAL, EOC_VAL, - SIZ_VAL, - COD_VAL, COC_VAL, RGN_VAL, QCD_VAL, QCC_VAL, POD_VAL, - TLM_VAL, PLM_VAL, PLT_VAL, PPM_VAL, PPT_VAL, - SOP_VAL, EPH_VAL, - COM_VAL -#ifdef USE_JPWL - , EPB_VAL, ESD_VAL, EPC_VAL, RED_VAL -#endif // USE_JPWL -#ifdef USE_JPSEC - , SEC_VAL -#endif // USE_JPSEC -}; - -// Marker names -static const char *marker_name[] = { - "SOC", "SOT", "SOD", "EOC", - "SIZ", - "COD", "COC", "RGN", "QCD", "QCC", "POD", - "TLM", "PLM", "PLT", "PPM", "PPT", - "SOP", "EPH", - "COM" -#ifdef USE_JPWL - , "EPB", "ESD", "EPC", "RED" -#endif // USE_JPWL -#ifdef USE_JPSEC - , "SEC" -#endif // USE_JPSEC -}; - -// Marker descriptions -static const char *marker_descr[] = { - "Start of codestream", "Start of tile-part", "Start of data", "End of codestream", - "Image and tile size", - "Coding style default", "Coding style component", "Region-of-interest", "Quantization default", - "Quantization component", "Progression order change, default", - "Tile-part lengths, main header", "Packet length, main header", "Packets length, tile-part header", - "Packed packet headers, main header", "Packed packet headers, tile-part header", - "Start of packet", "End of packet header", - "Comment and extension" -#ifdef USE_JPWL - , "Error Protection Block", "Error Sensitivity Descriptor", "Error Protection Capability", - "Residual Errors Descriptor" -#endif // USE_JPWL -#ifdef USE_JPSEC - , "Main security marker" -#endif // USE_JPSEC -}; - -void OPJParseThread::ParseJ2KFile(wxFile *m_file, wxFileOffset offset, wxFileOffset length, wxTreeItemId parentid) -{ - unsigned short int csiz = 0; - - // check if the file is opened - if (m_file->IsOpened()) - WriteText(wxT("File OK")); - else - return; - - // position at the beginning - m_file->Seek(offset, wxFromStart); - - // navigate the file - int m, inside_sod = 0, inside_sop = 0; - int nmarks = 0, maxmarks = 10000; - unsigned char onebyte[1]; - unsigned char twobytes[2], firstbyte, secondbyte; - unsigned char fourbytes[4]; - unsigned short int currmark; - unsigned short int currlen; - int lastPsot = 0, lastsotpos = 0; - - WriteText(wxT("Start search...")); - -// advancing macro -#define OPJ_ADVANCE(A) {offset += A; if (offset < length) m_file->Seek(offset, wxFromStart); else return;} - - // begin search - while ((offset < length) && (!m_file->Eof())) { - - // read one byte - if (m_file->Read(&firstbyte, 1) != 1) - break; - - // look for 0xFF - if (firstbyte == 0xFF) { - - // it is a possible marker - if (m_file->Read(&secondbyte, 1) != 1) - break; - else - currmark = (((unsigned short int) firstbyte) << 8) + (unsigned short int) secondbyte; - - } else { - - // nope, advance by one and search again - OPJ_ADVANCE(1); - continue; - } - - // search the marker - for (m = 0; m < J2KMARK_NUM; m++) { - if (currmark == marker_val[m]) - break; - } - - // marker not found - if (m == J2KMARK_NUM) { - // nope, advance by one and search again - OPJ_ADVANCE(1); - continue; - } - - // if we are inside SOD, only some markers are allowed - if (inside_sod) { - - // we are inside SOP - if (inside_sop) { - - } - - // randomly marker coincident data - if ((currmark != SOT_VAL) && - (currmark != EOC_VAL) && - (currmark != SOP_VAL) && - (currmark != EPH_VAL)) { - OPJ_ADVANCE(1); - continue; - } - - // possible SOT? - if ((currmark == SOT_VAL)) { - // too early SOT - if (offset < (lastsotpos + lastPsot)) { - OPJ_ADVANCE(1); - continue; - } - // we were not in the last tile - /*if (lastPsot != 0) { - OPJ_ADVANCE(1); - break; - }*/ - } - } - - // beyond this point, the marker MUST BE real - - // length of current marker segment - if ((currmark == SOD_VAL) || - (currmark == SOC_VAL) || - (currmark == EOC_VAL) || - (currmark == EPH_VAL)) - - // zero length markers - currlen = 0; - - else { - - // read length field - if (m_file->Read(twobytes, 2) != 2) - break; - - currlen = (((unsigned short int) twobytes[0]) << 8) + (unsigned short int) twobytes[1]; - } - - // here we pass to AppendItem() normal and selected item images (we - // suppose that selected image follows the normal one in the enum) - int image, imageSel; - image = m_tree->TreeCtrlIcon_Folder; - imageSel = image + 1; - - // append the marker - wxTreeItemId currid = m_tree->AppendItem(parentid, - wxString::Format(wxT("%03d: "), nmarks) + - wxString::FromAscii(marker_name[m]) + - wxString::Format(wxT(" (0x%04X)"), marker_val[m]), - image, imageSel, - new OPJMarkerData(wxT("MARK") + wxString::Format(wxT(" (%d)"), marker_val[m]), - m_tree->m_fname.GetFullPath(), offset, offset + currlen + 1) - ); - - // append some info - image = m_tree->TreeCtrlIcon_File; - imageSel = image + 1; - - // marker name - wxTreeItemId subcurrid1 = m_tree->AppendItem(currid, - wxT("*** ") + wxString::FromAscii(marker_descr[m]) + wxT(" ***"), - image, imageSel, - new OPJMarkerData(wxT("INFO")) - ); - m_tree->SetItemFont(subcurrid1, *wxITALIC_FONT); - - // position and length - wxTreeItemId subcurrid2 = m_tree->AppendItem(currid, - wxLongLong(offset).ToString() + wxT(" > ") + wxLongLong(offset + currlen + 1).ToString() + - wxT(", ") + wxString::Format(wxT("%d + 2 (%d)"), currlen, currlen + 2), - image, imageSel, - new OPJMarkerData(wxT("INFO")) - ); - - // give additional info on markers - switch (currmark) { - - ///////// - // SOP // - ///////// - case SOP_VAL: - { - // read packet number - if (m_file->Read(twobytes, 2) != 2) - break; - int packnum = STREAM_TO_UINT16(twobytes, 0); - - image = m_tree->TreeCtrlIcon_File; - imageSel = image + 1; - - wxTreeItemId subcurrid3 = m_tree->AppendItem(currid, - wxString::Format(wxT("Pack. no. %d"), packnum), - image, imageSel, - new OPJMarkerData(wxT("INFO")) - ); - inside_sop = 1; - }; - break; - -#ifdef USE_JPWL - ///////// - // RED // - ///////// - case RED_VAL: - { - if (m_file->Read(onebyte, 1) != 1) - break; - unsigned char pred = onebyte[0]; - - image = m_tree->TreeCtrlIcon_File; - imageSel = image + 1; - - wxString address[] = { - wxT("Packet addressing"), - wxT("Byte-range addressing"), - wxT("Packet-range addressing"), - wxT("Reserved") - }; - - wxTreeItemId subcurrid = m_tree->AppendItem(currid, - address[(pred & 0xC0) >> 6], - image, imageSel, - new OPJMarkerData(wxT("INFO")) - ); - - subcurrid = m_tree->AppendItem(currid, - wxString::Format(wxT("%d bytes range"), (((pred & 0x02) >> 1) + 1) * 2), - image, imageSel, - new OPJMarkerData(wxT("INFO")) - ); - - subcurrid = m_tree->AppendItem(currid, - pred & 0x01 ? wxT("Errors/erasures in codestream") : wxT("Error free codestream"), - image, imageSel, - new OPJMarkerData(wxT("INFO")) - ); - - subcurrid = m_tree->AppendItem(currid, - wxString::Format(wxT("Residual corruption level: %d"), (pred & 0x38) >> 3), - image, imageSel, - new OPJMarkerData(wxT("INFO")) - ); - - } - break; - - ///////// - // ESD // - ///////// - case ESD_VAL: - { - unsigned short int cesd; - if (csiz < 257) { - if (m_file->Read(onebyte, 1) != 1) - break; - cesd = onebyte[0]; - } else { - if (m_file->Read(twobytes, 2) != 2) - break; - cesd = STREAM_TO_UINT16(twobytes, 0); - } - - if (m_file->Read(onebyte, 1) != 1) - break; - unsigned char pesd = onebyte[0]; - - image = m_tree->TreeCtrlIcon_File; - imageSel = image + 1; - - wxTreeItemId subcurrid = m_tree->AppendItem(currid, - pesd & 0x01 ? wxT("Comp. average") : wxString::Format(wxT("Comp. no. %d"), cesd), - image, imageSel, - new OPJMarkerData(wxT("INFO")) - ); - - wxString meth[] = { - wxT("Relative error sensitivity"), - wxT("MSE"), - wxT("MSE reduction"), - wxT("PSNR"), - wxT("PSNR increase"), - wxT("MAXERR (absolute peak error)"), - wxT("TSE (total squared error)"), - wxT("Reserved") - }; - - subcurrid = m_tree->AppendItem(currid, - meth[(pesd & 0x38) >> 3], - image, imageSel, - new OPJMarkerData(wxT("INFO")) - ); - - wxString address[] = { - wxT("Packet addressing"), - wxT("Byte-range addressing"), - wxT("Packet-range addressing"), - wxT("Reserved") - }; - - subcurrid = m_tree->AppendItem(currid, - address[(pesd & 0xC0) >> 6], - image, imageSel, - new OPJMarkerData(wxT("INFO")) - ); - - subcurrid = m_tree->AppendItem(currid, - wxString::Format(wxT("%d bytes/value, %d bytes range"), ((pesd & 0x04) >> 2) + 1, (((pesd & 0x02) >> 1) + 1) * 2), - image, imageSel, - new OPJMarkerData(wxT("INFO")) - ); - - } - break; - - ///////// - // EPC // - ///////// - case EPC_VAL: - { - if (m_file->Read(twobytes, 2) != 2) - break; - unsigned short int pcrc = STREAM_TO_UINT16(twobytes, 0); - - if (m_file->Read(fourbytes, 4) != 4) - break; - unsigned long int dl = STREAM_TO_UINT32(fourbytes, 0); - - if (m_file->Read(onebyte, 1) != 1) - break; - unsigned char pepc = onebyte[0]; - - image = m_tree->TreeCtrlIcon_File; - imageSel = image + 1; - - wxTreeItemId subcurrid = m_tree->AppendItem(currid, - wxString::Format(wxT("CRC-16 = 0x%x"), pcrc), - image, imageSel, - new OPJMarkerData(wxT("INFO")) - ); - - subcurrid = m_tree->AppendItem(currid, - wxString::Format(wxT("Tot. length = %d"), dl), - image, imageSel, - new OPJMarkerData(wxT("INFO")) - ); - - subcurrid = m_tree->AppendItem(currid, - wxString::Format(wxT("%s%s%s%s"), - pepc & 0x10 ? wxT("ESD, ") : wxT(""), - pepc & 0x20 ? wxT("RED, ") : wxT(""), - pepc & 0x40 ? wxT("EPB, ") : wxT(""), - pepc & 0x80 ? wxT("Info") : wxT("") - ), - image, imageSel, - new OPJMarkerData(wxT("INFO")) - ); - - } - break; - - ///////// - // EPB // - ///////// - case EPB_VAL: - { - if (m_file->Read(onebyte, 1) != 1) - break; - unsigned char depb = onebyte[0]; - - if (m_file->Read(fourbytes, 4) != 4) - break; - unsigned long int ldpepb = STREAM_TO_UINT32(fourbytes, 0); - - if (m_file->Read(fourbytes, 4) != 4) - break; - unsigned long int pepb = STREAM_TO_UINT32(fourbytes, 0); - - image = m_tree->TreeCtrlIcon_File; - imageSel = image + 1; - - wxTreeItemId subcurrid = m_tree->AppendItem(currid, - wxString::Format(wxT("No. %d, %slatest, %spacked"), - depb & 0x3F, - depb & 0x40 ? wxT("") : wxT("not "), - depb & 0x80 ? wxT("") : wxT("un")), - image, imageSel, - new OPJMarkerData(wxT("INFO")) - ); - - subcurrid = m_tree->AppendItem(currid, - wxString::Format(wxT("%d bytes protected"), ldpepb), - image, imageSel, - new OPJMarkerData(wxT("INFO")) - ); - - if (pepb == 0x00000000) - - subcurrid = m_tree->AppendItem(currid, - wxT("Predefined codes"), - image, imageSel, - new OPJMarkerData(wxT("INFO")) - ); - - else if ((pepb >= 0x10000000) && (pepb <= 0x1FFFFFFF)) { - - wxString text = wxT("CRC code"); - if (pepb == 0x10000000) - text << wxT(", CCITT (X25) 16 bits"); - else if (pepb == 0x10000001) - text << wxT(", Ethernet 32 bits"); - else - text << wxT(", JPWL RA"); - subcurrid = m_tree->AppendItem(currid, - text, - image, imageSel, - new OPJMarkerData(wxT("INFO")) - ); - - } else if ((pepb >= 0x20000000) && (pepb <= 0x2FFFFFFF)) { - - wxString text; - subcurrid = m_tree->AppendItem(currid, - wxString::Format(wxT("RS code, RS(%d, %d)"), - (pepb & 0x0000FF00) >> 8, - (pepb & 0x000000FF)), - image, imageSel, - new OPJMarkerData(wxT("INFO")) - ); - - } else if ((pepb >= 0x30000000) && (pepb <= 0x3FFFFFFE)) - - subcurrid = m_tree->AppendItem(currid, - wxT("JPWL RA"), - image, imageSel, - new OPJMarkerData(wxT("INFO")) - ); - - else if (pepb == 0xFFFFFFFF) - - subcurrid = m_tree->AppendItem(currid, - wxT("No method"), - image, imageSel, - new OPJMarkerData(wxT("INFO")) - ); - - } - break; -#endif // USE_JPWL - -#ifdef USE_JPSEC - case SEC_VAL: - { - - } - break; -#endif // USE_JPSEC - - ///////// - // SIZ // - ///////// - case SIZ_VAL: - { - int c; - - if (m_file->Read(twobytes, 2) != 2) - break; - unsigned short int rsiz = STREAM_TO_UINT16(twobytes, 0); - - if (m_file->Read(fourbytes, 4) != 4) - break; - unsigned long int xsiz = STREAM_TO_UINT32(fourbytes, 0); - - if (m_file->Read(fourbytes, 4) != 4) - break; - unsigned long int ysiz = STREAM_TO_UINT32(fourbytes, 0); - - if (m_file->Read(fourbytes, 4) != 4) - break; - unsigned long int xosiz = STREAM_TO_UINT32(fourbytes, 0); - - if (m_file->Read(fourbytes, 4) != 4) - break; - unsigned long int yosiz = STREAM_TO_UINT32(fourbytes, 0); - - if (m_file->Read(fourbytes, 4) != 4) - break; - unsigned long int xtsiz = STREAM_TO_UINT32(fourbytes, 0); - this->m_tree->m_childframe->m_twidth = xtsiz; - - if (m_file->Read(fourbytes, 4) != 4) - break; - unsigned long int ytsiz = STREAM_TO_UINT32(fourbytes, 0); - this->m_tree->m_childframe->m_theight = ytsiz; - - if (m_file->Read(fourbytes, 4) != 4) - break; - unsigned long int xtosiz = STREAM_TO_UINT32(fourbytes, 0); - this->m_tree->m_childframe->m_tx = xtosiz; - - if (m_file->Read(fourbytes, 4) != 4) - break; - unsigned long int ytosiz = STREAM_TO_UINT32(fourbytes, 0); - this->m_tree->m_childframe->m_ty = ytosiz; - - if (m_file->Read(twobytes, 2) != 2) - break; - csiz = STREAM_TO_UINT16(twobytes, 0); - - bool equaldepth = true, equalsize = true; - unsigned char *ssiz = new unsigned char(csiz); - unsigned char *xrsiz = new unsigned char(csiz); - unsigned char *yrsiz = new unsigned char(csiz); - - for (c = 0; c < csiz; c++) { - - if (m_file->Read(&ssiz[c], 1) != 1) - break; - - if (c > 0) - equaldepth = equaldepth && (ssiz[c] == ssiz[c - 1]); - - if (m_file->Read(&xrsiz[c], 1) != 1) - break; - - if (m_file->Read(&yrsiz[c], 1) != 1) - break; - - if (c > 0) - equalsize = equalsize && (xrsiz[c] == xrsiz[c - 1]) && (yrsiz[c] == yrsiz[c - 1]) ; - - } - - if (equaldepth && equalsize) - wxTreeItemId subcurrid3 = m_tree->AppendItem(currid, - wxString::Format(wxT("I: %dx%d (%d, %d), %d c., %d%s bpp"), - xsiz, ysiz, - xosiz, yosiz, - csiz, ((ssiz[0] & 0x7F) + 1), - (ssiz[0] & 0x80) ? wxT("s") : wxT("u")), - image, imageSel, - new OPJMarkerData(wxT("INFO")) - ); - else - wxTreeItemId subcurrid3 = m_tree->AppendItem(currid, - wxString::Format(wxT("I: %dx%d (%d, %d), %d c."), - xsiz, ysiz, - xosiz, yosiz, - csiz), - image, imageSel, - new OPJMarkerData(wxT("INFO")) - ); - - wxTreeItemId subcurrid3 = m_tree->AppendItem(currid, - wxString::Format(wxT("T: %dx%d (%d, %d)"), - xtsiz, ytsiz, - xtosiz, ytosiz), - image, imageSel, - new OPJMarkerData(wxT("INFO")) - ); - - image = m_tree->TreeCtrlIcon_Folder; - imageSel = image + 1; - - wxTreeItemId subcurrid4 = m_tree->AppendItem(currid, - wxT("Components"), - image, imageSel, - new OPJMarkerData(wxT("INFO")) - ); - - image = m_tree->TreeCtrlIcon_File; - imageSel = image + 1; - - for (c = 0; c < csiz; c++) { - - wxTreeItemId subcurrid5 = m_tree->AppendItem(subcurrid4, - wxString::Format(wxT("#%d: %dx%d, %d%s bpp"), - c, - xsiz/xrsiz[c], ysiz/yrsiz[c], - ((ssiz[c] & 0x7F) + 1), - (ssiz[c] & 0x80) ? wxT("s") : wxT("u")), - image, imageSel, - new OPJMarkerData(wxT("INFO")) - ); - - } - - }; - break; - - ///////// - // SOT // - ///////// - case SOT_VAL: - { - if (m_file->Read(twobytes, 2) != 2) - break; - unsigned short int isot = STREAM_TO_UINT16(twobytes, 0); - - if (m_file->Read(fourbytes, 4) != 4) - break; - unsigned long int psot = STREAM_TO_UINT32(fourbytes, 0); - - if (m_file->Read(onebyte, 1) != 1) - break; - unsigned char tpsot = onebyte[0]; - - if (m_file->Read(onebyte, 1) != 1) - break; - unsigned char tnsot = onebyte[0]; - - wxTreeItemId subcurrid3 = m_tree->AppendItem(currid, - wxString::Format(wxT("tile %d, psot = %d, part %d of %d"), isot, psot, tpsot, tnsot), - image, imageSel, - new OPJMarkerData(wxT("INFO")) - ); - - lastPsot = psot; - lastsotpos = offset; - inside_sod = 0; - }; - break; - - ///////// - // COC // - ///////// - case COC_VAL: - { - unsigned short int ccoc; - if (csiz < 257) { - if (m_file->Read(onebyte, 1) != 1) - break; - ccoc = onebyte[0]; - } else { - if (m_file->Read(twobytes, 2) != 2) - break; - ccoc = STREAM_TO_UINT16(twobytes, 0); - } - - if (m_file->Read(onebyte, 1) != 1) - break; - unsigned char scoc = onebyte[0]; - - wxTreeItemId subcurrid = m_tree->AppendItem(currid, - wxString::Format(wxT("Comp. no. %d"), ccoc), - image, imageSel, - new OPJMarkerData(wxT("INFO")) - ); - - wxString text; - if (scoc & 0x01) - text << wxT("Partitioned entropy coder"); - else - text << wxT("Unpartitioned entropy coder"); - - subcurrid = m_tree->AppendItem(currid, - text, - image, imageSel, - new OPJMarkerData(wxT("INFO")) - ); - - if (m_file->Read(onebyte, 1) != 1) - break; - unsigned char decomplevs = onebyte[0]; - - if (m_file->Read(onebyte, 1) != 1) - break; - unsigned char cbswidth = onebyte[0]; - - if (m_file->Read(onebyte, 1) != 1) - break; - unsigned char cbsheight = onebyte[0]; - - if (m_file->Read(onebyte, 1) != 1) - break; - unsigned char cbstyle = onebyte[0]; - - if (m_file->Read(onebyte, 1) != 1) - break; - unsigned char transform = onebyte[0]; - - subcurrid = m_tree->AppendItem(currid, - wxString::Format(wxT("%d levels (%d resolutions)"), decomplevs, decomplevs + 1), - image, imageSel, - new OPJMarkerData(wxT("INFO")) - ); - - if (transform & 0x01) - text = wxT("5-3 reversible wavelet"); - else - text = wxT("9-7 irreversible wavelet"); - subcurrid = m_tree->AppendItem(currid, - text, - image, imageSel, - new OPJMarkerData(wxT("INFO")) - ); - - subcurrid = m_tree->AppendItem(currid, - wxString::Format(wxT("Code-blocks: %dx%d"), 1 << ((cbswidth & 0x0F) + 2), 1 << ((cbsheight & 0x0F) + 2)), - image, imageSel, - new OPJMarkerData(wxT("INFO")) - ); - - image = m_tree->TreeCtrlIcon_Folder; - imageSel = image + 1; - - wxTreeItemId subcurrid3 = m_tree->AppendItem(currid, - wxT("Coding styles"), - image, imageSel, - new OPJMarkerData(wxT("INFO")) - ); - - image = m_tree->TreeCtrlIcon_File; - imageSel = image + 1; - - if (cbstyle & 0x01) - text = wxT("Selective arithmetic coding bypass"); - else - text = wxT("No selective arithmetic coding bypass"); - wxTreeItemId subcurrid4 = m_tree->AppendItem(subcurrid3, - text, - image, imageSel, - new OPJMarkerData(wxT("INFO")) - ); - - if (cbstyle & 0x02) - text = wxT("Reset context probabilities on coding pass boundaries"); - else - text = wxT("No reset of context probabilities on coding pass boundaries"); - subcurrid4 = m_tree->AppendItem(subcurrid3, - text, - image, imageSel, - new OPJMarkerData(wxT("INFO")) - ); - - if (cbstyle & 0x04) - text = wxT("Termination on each coding passs"); - else - text = wxT("No termination on each coding pass"); - subcurrid4 = m_tree->AppendItem(subcurrid3, - text, - image, imageSel, - new OPJMarkerData(wxT("INFO")) - ); - - if (cbstyle & 0x08) - text = wxT("Vertically stripe causal context"); - else - text = wxT("No vertically stripe causal context"); - subcurrid4 = m_tree->AppendItem(subcurrid3, - text, - image, imageSel, - new OPJMarkerData(wxT("INFO")) - ); - - if (cbstyle & 0x10) - text = wxT("Predictable termination"); - else - text = wxT("No predictable termination"); - subcurrid4 = m_tree->AppendItem(subcurrid3, - text, - image, imageSel, - new OPJMarkerData(wxT("INFO")) - ); - - if (cbstyle & 0x20) - text = wxT("Segmentation symbols are used"); - else - text = wxT("No segmentation symbols are used"); - subcurrid4 = m_tree->AppendItem(subcurrid3, - text, - image, imageSel, - new OPJMarkerData(wxT("INFO")) - ); - - } - break; - - ///////// - // COD // - ///////// - case COD_VAL: - { - if (m_file->Read(onebyte, 1) != 1) - break; - unsigned char scod = onebyte[0]; - - wxString text; - - if (scod & 0x01) - text << wxT("Partitioned entropy coder"); - else - text << wxT("Unpartitioned entropy coder"); - - wxTreeItemId subcurrid3 = m_tree->AppendItem(currid, - text, - image, imageSel, - new OPJMarkerData(wxT("INFO")) - ); - - text = wxT(""); - if (scod & 0x02) - text << wxT("Possible SOPs"); - else - text << wxT("No SOPs"); - - if (scod & 0x04) - text << wxT(", possible EPHs"); - else - text << wxT(", no EPHs"); - - subcurrid3 = m_tree->AppendItem(currid, - text, - image, imageSel, - new OPJMarkerData(wxT("INFO")) - ); - - if (m_file->Read(onebyte, 1) != 1) - break; - unsigned char progord = onebyte[0]; - - if (m_file->Read(twobytes, 2) != 2) - break; - unsigned short int numlayers = STREAM_TO_UINT16(twobytes, 0); - - if (m_file->Read(onebyte, 1) != 1) - break; - unsigned char mctransform = onebyte[0]; - - if (m_file->Read(onebyte, 1) != 1) - break; - unsigned char decomplevs = onebyte[0]; - - if (m_file->Read(onebyte, 1) != 1) - break; - unsigned char cbswidth = onebyte[0]; - - if (m_file->Read(onebyte, 1) != 1) - break; - unsigned char cbsheight = onebyte[0]; - - if (m_file->Read(onebyte, 1) != 1) - break; - unsigned char cbstyle = onebyte[0]; - - if (m_file->Read(onebyte, 1) != 1) - break; - unsigned char transform = onebyte[0]; - - subcurrid3 = m_tree->AppendItem(currid, - wxString::Format(wxT("%d levels (%d resolutions)"), decomplevs, decomplevs + 1), - image, imageSel, - new OPJMarkerData(wxT("INFO")) - ); - - text = wxT(""); - switch (progord) { - case (0): - text << wxT("LRCP"); - break; - case (1): - text << wxT("RLCP"); - break; - case (2): - text << wxT("LRCP"); - break; - case (3): - text << wxT("RPCL"); - break; - case (4): - text << wxT("CPRL"); - break; - default: - text << wxT("unknown progression"); - break; - } - text << wxString::Format(wxT(", %d layers"), numlayers); - if (transform & 0x01) - text << wxT(", 5-3 rev."); - else - text << wxT(", 9-7 irr."); - subcurrid3 = m_tree->AppendItem(currid, - text, - image, imageSel, - new OPJMarkerData(wxT("INFO")) - ); - - subcurrid3 = m_tree->AppendItem(currid, - wxString::Format(wxT("Code-blocks: %dx%d"), 1 << ((cbswidth & 0x0F) + 2), 1 << ((cbsheight & 0x0F) + 2)), - image, imageSel, - new OPJMarkerData(wxT("INFO")) - ); - - switch (mctransform) { - case (0): - { - text = wxT("No MCT"); - } - break; - case (1): - { - text = wxT("Reversible MCT on 0, 1, 2"); - } - break; - case (2): - { - text = wxT("Irreversible MCT on 0, 1, 2"); - } - break; - default: - { - text = wxT("Unknown"); - } - break; - }; - subcurrid3 = m_tree->AppendItem(currid, - text, - image, imageSel, - new OPJMarkerData(wxT("INFO")) - ); - - - image = m_tree->TreeCtrlIcon_Folder; - imageSel = image + 1; - - subcurrid3 = m_tree->AppendItem(currid, - wxT("Coding styles"), - image, imageSel, - new OPJMarkerData(wxT("INFO")) - ); - - image = m_tree->TreeCtrlIcon_File; - imageSel = image + 1; - - if (cbstyle & 0x01) - text = wxT("Selective arithmetic coding bypass"); - else - text = wxT("No selective arithmetic coding bypass"); - wxTreeItemId subcurrid4 = m_tree->AppendItem(subcurrid3, - text, - image, imageSel, - new OPJMarkerData(wxT("INFO")) - ); - - if (cbstyle & 0x02) - text = wxT("Reset context probabilities on coding pass boundaries"); - else - text = wxT("No reset of context probabilities on coding pass boundaries"); - subcurrid4 = m_tree->AppendItem(subcurrid3, - text, - image, imageSel, - new OPJMarkerData(wxT("INFO")) - ); - - if (cbstyle & 0x04) - text = wxT("Termination on each coding passs"); - else - text = wxT("No termination on each coding pass"); - subcurrid4 = m_tree->AppendItem(subcurrid3, - text, - image, imageSel, - new OPJMarkerData(wxT("INFO")) - ); - - if (cbstyle & 0x08) - text = wxT("Vertically stripe causal context"); - else - text = wxT("No vertically stripe causal context"); - subcurrid4 = m_tree->AppendItem(subcurrid3, - text, - image, imageSel, - new OPJMarkerData(wxT("INFO")) - ); - - if (cbstyle & 0x10) - text = wxT("Predictable termination"); - else - text = wxT("No predictable termination"); - subcurrid4 = m_tree->AppendItem(subcurrid3, - text, - image, imageSel, - new OPJMarkerData(wxT("INFO")) - ); - - if (cbstyle & 0x20) - text = wxT("Segmentation symbols are used"); - else - text = wxT("No segmentation symbols are used"); - subcurrid4 = m_tree->AppendItem(subcurrid3, - text, - image, imageSel, - new OPJMarkerData(wxT("INFO")) - ); - - }; - break; - - ///////// - // QCC // - ///////// - case QCC_VAL: - { - unsigned short int cqcc; - if (csiz < 257) { - if (m_file->Read(onebyte, 1) != 1) - break; - cqcc = onebyte[0]; - } else { - if (m_file->Read(twobytes, 2) != 2) - break; - cqcc = STREAM_TO_UINT16(twobytes, 0); - } - - wxTreeItemId subcurrid = m_tree->AppendItem(currid, - wxString::Format(wxT("Comp. no. %d"), cqcc), - image, imageSel, - new OPJMarkerData(wxT("INFO")) - ); - - if (m_file->Read(onebyte, 1) != 1) - break; - unsigned char sqcc = onebyte[0]; - - wxString text; - switch (sqcc & 0x1F) { - case (0): - text = wxT("No quantization"); - break; - case (1): - text = wxT("Scalar implicit"); - break; - case (2): - text = wxT("Scalar explicit"); - break; - default: - text = wxT("Unknown"); - break; - } - text << wxString::Format(wxT(", %d guard bits"), (sqcc & 0xE0) >> 5); - wxTreeItemId subcurrid3 = m_tree->AppendItem(currid, - text, - image, imageSel, - new OPJMarkerData(wxT("INFO")) - ); - - } - break; - - ///////// - // QCD // - ///////// - case QCD_VAL: - { - if (m_file->Read(onebyte, 1) != 1) - break; - unsigned char sqcd = onebyte[0]; - - wxString text; - switch (sqcd & 0x1F) { - case (0): - text = wxT("No quantization"); - break; - case (1): - text = wxT("Scalar implicit"); - break; - case (2): - text = wxT("Scalar explicit"); - break; - default: - text = wxT("Unknown"); - break; - } - text << wxString::Format(wxT(", %d guard bits"), (sqcd & 0xE0) >> 5); - wxTreeItemId subcurrid3 = m_tree->AppendItem(currid, - text, - image, imageSel, - new OPJMarkerData(wxT("INFO")) - ); - - }; - break; - - ///////// - // COM // - ///////// - case COM_VAL: - { - #define showlen 25 - char comment[showlen]; - wxString comments; - - if (m_file->Read(twobytes, 2) != 2) - break; - unsigned short int rcom = STREAM_TO_UINT16(twobytes, 0); - - wxString text; - if (rcom == 0) - text = wxT("Binary values"); - else if (rcom == 1) - text = wxT("ISO 8859-1 (latin-1) values"); - else if (rcom < 65535) - text = wxT("Reserved for registration"); - else - text = wxT("Reserved for extension"); - wxTreeItemId subcurrid3 = m_tree->AppendItem(currid, - text, - image, imageSel, - new OPJMarkerData(wxT("INFO")) - ); - - if (m_file->Read(comment, showlen) != showlen) - break; - comments = wxString::FromAscii(comment).Truncate(wxMin(showlen, currlen - 4)); - if ((currlen - 4) > showlen) - comments << wxT("..."); - subcurrid3 = m_tree->AppendItem(currid, - comments, - image, imageSel, - new OPJMarkerData(wxT("INFO")) - ); - }; - break; - - ///////// - // TLM // - ///////// - case TLM_VAL: - { - if (m_file->Read(onebyte, 1) != 1) - break; - unsigned char ztlm = onebyte[0]; - - if (m_file->Read(onebyte, 1) != 1) - break; - unsigned char stlm = onebyte[0]; - - image = m_tree->TreeCtrlIcon_File; - imageSel = image + 1; - - wxTreeItemId subcurrid3 = m_tree->AppendItem(currid, - wxString::Format(wxT("TLM #%d"), ztlm), - image, imageSel, - new OPJMarkerData(wxT("INFO")) - ); - - subcurrid3 = m_tree->AppendItem(currid, - wxString::Format(wxT("%d bits/index, %d bits/length"), - 8 * ((stlm & 0x30) >> 4), 16 + 16 * ((stlm & 0x40) >> 6)), - image, imageSel, - new OPJMarkerData(wxT("INFO")) - ); - - int n, numparts; - - numparts = (currlen - 2) / ( ((stlm & 0x30) >> 4) + 2 + 2 * ((stlm & 0x40) >> 6)); - - image = m_tree->TreeCtrlIcon_Folder; - imageSel = image + 1; - - subcurrid3 = m_tree->AppendItem(currid, - wxT("Tile parts"), - image, imageSel, - new OPJMarkerData(wxT("INFO")) - ); - - image = m_tree->TreeCtrlIcon_File; - imageSel = image + 1; - - for (n = 0; n < numparts; n++) { - - unsigned short int ttlm; - unsigned long int ptlm; - - switch (((stlm & 0x30) >> 4)) { - - case 0: - ttlm = 0; - break; - - case 1: - if (m_file->Read(onebyte, 1) != 1) - break; - ttlm = onebyte[0]; - break; - - case 2: - if (m_file->Read(twobytes, 2) != 2) - break; - ttlm = STREAM_TO_UINT16(twobytes, 0); - break; - - } - - switch (((stlm & 0x40) >> 6)) { - - case 0: - if (m_file->Read(twobytes, 2) != 2) - break; - ptlm = STREAM_TO_UINT16(twobytes, 0); - break; - - case 1: - if (m_file->Read(fourbytes, 4) != 4) - break; - ptlm = STREAM_TO_UINT32(fourbytes, 0); - break; - - } - - wxTreeItemId subcurrid4 = m_tree->AppendItem(subcurrid3, - wxString::Format(wxT("Tile %d: %d bytes"), ttlm, ptlm), - image, imageSel, - new OPJMarkerData(wxT("INFO")) - ); - - } - - } - break; - - ///////// - // POD // - ///////// - case POD_VAL: - { - int n, numchanges; - - if (csiz < 257) - numchanges = (currlen - 2) / 7; - else - numchanges = (currlen - 2) / 9; - - for (n = 0; n < numchanges; n++) { - - image = m_tree->TreeCtrlIcon_Folder; - imageSel = image + 1; - - wxTreeItemId subcurrid3 = m_tree->AppendItem(currid, - wxString::Format(wxT("Change #%d"), n), - image, imageSel, - new OPJMarkerData(wxT("INFO")) - ); - - if (m_file->Read(onebyte, 1) != 1) - break; - unsigned char rspod = onebyte[0]; - - unsigned short int cspod; - if (csiz < 257) { - if (m_file->Read(onebyte, 1) != 1) - break; - cspod = onebyte[0]; - } else { - if (m_file->Read(twobytes, 2) != 2) - break; - cspod = STREAM_TO_UINT16(twobytes, 0); - } - - if (m_file->Read(twobytes, 2) != 2) - break; - unsigned short int lyepod = STREAM_TO_UINT16(twobytes, 0); - - if (m_file->Read(onebyte, 1) != 1) - break; - unsigned char repod = onebyte[0]; - - unsigned short int cepod; - if (csiz < 257) { - if (m_file->Read(onebyte, 1) != 1) - break; - cepod = onebyte[0]; - } else { - if (m_file->Read(twobytes, 2) != 2) - break; - cepod = STREAM_TO_UINT16(twobytes, 0); - } - - if (m_file->Read(onebyte, 1) != 1) - break; - unsigned char ppod = onebyte[0]; - - image = m_tree->TreeCtrlIcon_File; - imageSel = image + 1; - - wxTreeItemId subcurrid4 = m_tree->AppendItem(subcurrid3, - wxString::Format(wxT("%d <= Resolution < %d"), rspod, repod), - image, imageSel, - new OPJMarkerData(wxT("INFO")) - ); - - subcurrid4 = m_tree->AppendItem(subcurrid3, - wxString::Format(wxT("%d <= Component < %d"), cspod, cepod), - image, imageSel, - new OPJMarkerData(wxT("INFO")) - ); - - subcurrid4 = m_tree->AppendItem(subcurrid3, - wxString::Format(wxT("0 <= Layer < %d"), lyepod), - image, imageSel, - new OPJMarkerData(wxT("INFO")) - ); - - wxString text = wxT(""); - switch (ppod) { - case (0): - text << wxT("LRCP"); - break; - case (1): - text << wxT("RLCP"); - break; - case (2): - text << wxT("LRCP"); - break; - case (3): - text << wxT("RPCL"); - break; - case (4): - text << wxT("CPRL"); - break; - default: - text << wxT("unknown progression"); - break; - } - subcurrid4 = m_tree->AppendItem(subcurrid3, - text, - image, imageSel, - new OPJMarkerData(wxT("INFO")) - ); - } - - } - break; - - ///////// - // SOD // - ///////// - case SOD_VAL: - { - inside_sod = 1; - }; - break; - - default: - break; - - } - - // increment number of markers - if (nmarks++ >= maxmarks) { - WriteText(wxT("Maximum amount of markers exceeded")); - break; - } - - // advance position - OPJ_ADVANCE(currlen + 2); - } - - WriteText(wxT("Search finished")); -} +/* + * Copyright (c) 2007, Digital Signal Processing Laboratory, Università degli studi di Perugia (UPG), Italy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are 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. + */ +#include "OPJViewer.h" + +/* From little endian to big endian, 2 bytes */ +#define BYTE_SWAP2(X) ((X & 0x00FF) << 8) | ((X & 0xFF00) >> 8) +#define BYTE_SWAP4(X) ((X & 0x000000FF) << 24) | ((X & 0x0000FF00) << 8) | ((X & 0x00FF0000) >> 8) | ((X & 0xFF000000) >> 24) + +/* From codestream to int values */ +#define STREAM_TO_UINT32(C, P) (((unsigned long int) (C)[(P) + 0] << 24) + \ + ((unsigned long int) (C)[(P) + 1] << 16) + \ + ((unsigned long int) (C)[(P) + 2] << 8) + \ + ((unsigned long int) (C)[(P) + 3] << 0)) + +#define STREAM_TO_UINT16(C, P) (((unsigned long int) (C)[(P) + 0] << 8) + \ + ((unsigned long int) (C)[(P) + 1] << 0)) + + +/* Markers values */ +#define J2KMARK_NUM 24 +enum { + SOC_VAL = 0xFF4F, + SOT_VAL = 0xFF90, + SOD_VAL = 0xFF93, + EOC_VAL = 0xFFD9, + SIZ_VAL = 0xFF51, + COD_VAL = 0xFF52, + COC_VAL = 0xFF53, + RGN_VAL = 0xFF5E, + QCD_VAL = 0xFF5C, + QCC_VAL = 0xFF5D, + POD_VAL = 0xFF5F, + TLM_VAL = 0xFF55, + PLM_VAL = 0xFF57, + PLT_VAL = 0xFF58, + PPM_VAL = 0xFF60, + PPT_VAL = 0xFF61, + SOP_VAL = 0xFF91, + EPH_VAL = 0xFF92, + COM_VAL = 0xFF64 +#ifdef USE_JPWL + , EPB_VAL = 0xFF66, + ESD_VAL = 0xFF67, + EPC_VAL = 0xFF68, + RED_VAL = 0xFF69 + /*, EPB_VAL = 0xFF96, + ESD_VAL = 0xFF98, + EPC_VAL = 0xFF97, + RED_VAL = 0xFF99*/ +#endif // USE_JPWL +#ifdef USE_JPSEC + , SEC_VAL = 0xFF65 +#endif // USE_JPSEC +}; + +// All the markers in one vector +unsigned short int marker_val[] = { + SOC_VAL, SOT_VAL, SOD_VAL, EOC_VAL, + SIZ_VAL, + COD_VAL, COC_VAL, RGN_VAL, QCD_VAL, QCC_VAL, POD_VAL, + TLM_VAL, PLM_VAL, PLT_VAL, PPM_VAL, PPT_VAL, + SOP_VAL, EPH_VAL, + COM_VAL +#ifdef USE_JPWL + , EPB_VAL, ESD_VAL, EPC_VAL, RED_VAL +#endif // USE_JPWL +#ifdef USE_JPSEC + , SEC_VAL +#endif // USE_JPSEC +}; + +// Marker names +static const char *marker_name[] = { + "SOC", "SOT", "SOD", "EOC", + "SIZ", + "COD", "COC", "RGN", "QCD", "QCC", "POD", + "TLM", "PLM", "PLT", "PPM", "PPT", + "SOP", "EPH", + "COM" +#ifdef USE_JPWL + , "EPB", "ESD", "EPC", "RED" +#endif // USE_JPWL +#ifdef USE_JPSEC + , "SEC" +#endif // USE_JPSEC +}; + +// Marker descriptions +static const char *marker_descr[] = { + "Start of codestream", "Start of tile-part", "Start of data", "End of codestream", + "Image and tile size", + "Coding style default", "Coding style component", "Region-of-interest", "Quantization default", + "Quantization component", "Progression order change, default", + "Tile-part lengths, main header", "Packet length, main header", "Packets length, tile-part header", + "Packed packet headers, main header", "Packed packet headers, tile-part header", + "Start of packet", "End of packet header", + "Comment and extension" +#ifdef USE_JPWL + , "Error Protection Block", "Error Sensitivity Descriptor", "Error Protection Capability", + "Residual Errors Descriptor" +#endif // USE_JPWL +#ifdef USE_JPSEC + , "Main security marker" +#endif // USE_JPSEC +}; + +void OPJParseThread::ParseJ2KFile(wxFile *m_file, wxFileOffset offset, wxFileOffset length, wxTreeItemId parentid) +{ + unsigned short int csiz = 0; + + // check if the file is opened + if (m_file->IsOpened()) + WriteText(wxT("File OK")); + else + return; + + // position at the beginning + m_file->Seek(offset, wxFromStart); + + // navigate the file + int m, inside_sod = 0, inside_sop = 0; + int nmarks = 0, maxmarks = 10000; + unsigned char onebyte[1]; + unsigned char twobytes[2], firstbyte, secondbyte; + unsigned char fourbytes[4]; + unsigned short int currmark; + unsigned short int currlen; + int lastPsot = 0, lastsotpos = 0; + + WriteText(wxT("Start search...")); + +// advancing macro +#define OPJ_ADVANCE(A) {offset += A; if (offset < length) m_file->Seek(offset, wxFromStart); else return;} + + // begin search + while ((offset < length) && (!m_file->Eof())) { + + // read one byte + if (m_file->Read(&firstbyte, 1) != 1) + break; + + // look for 0xFF + if (firstbyte == 0xFF) { + + // it is a possible marker + if (m_file->Read(&secondbyte, 1) != 1) + break; + else + currmark = (((unsigned short int) firstbyte) << 8) + (unsigned short int) secondbyte; + + } else { + + // nope, advance by one and search again + OPJ_ADVANCE(1); + continue; + } + + // search the marker + for (m = 0; m < J2KMARK_NUM; m++) { + if (currmark == marker_val[m]) + break; + } + + // marker not found + if (m == J2KMARK_NUM) { + // nope, advance by one and search again + OPJ_ADVANCE(1); + continue; + } + + // if we are inside SOD, only some markers are allowed + if (inside_sod) { + + // we are inside SOP + if (inside_sop) { + + } + + // randomly marker coincident data + if ((currmark != SOT_VAL) && + (currmark != EOC_VAL) && + (currmark != SOP_VAL) && + (currmark != EPH_VAL)) { + OPJ_ADVANCE(1); + continue; + } + + // possible SOT? + if ((currmark == SOT_VAL)) { + // too early SOT + if (offset < (lastsotpos + lastPsot)) { + OPJ_ADVANCE(1); + continue; + } + // we were not in the last tile + /*if (lastPsot != 0) { + OPJ_ADVANCE(1); + break; + }*/ + } + } + + // beyond this point, the marker MUST BE real + + // length of current marker segment + if ((currmark == SOD_VAL) || + (currmark == SOC_VAL) || + (currmark == EOC_VAL) || + (currmark == EPH_VAL)) + + // zero length markers + currlen = 0; + + else { + + // read length field + if (m_file->Read(twobytes, 2) != 2) + break; + + currlen = (((unsigned short int) twobytes[0]) << 8) + (unsigned short int) twobytes[1]; + } + + // here we pass to AppendItem() normal and selected item images (we + // suppose that selected image follows the normal one in the enum) + int image, imageSel; + image = m_tree->TreeCtrlIcon_Folder; + imageSel = image + 1; + + // append the marker + wxTreeItemId currid = m_tree->AppendItem(parentid, + wxString::Format(wxT("%03d: "), nmarks) + + wxString::FromAscii(marker_name[m]) + + wxString::Format(wxT(" (0x%04X)"), marker_val[m]), + image, imageSel, + new OPJMarkerData(wxT("MARK") + wxString::Format(wxT(" (%d)"), marker_val[m]), + m_tree->m_fname.GetFullPath(), offset, offset + currlen + 1) + ); + + // append some info + image = m_tree->TreeCtrlIcon_File; + imageSel = image + 1; + + // marker name + wxTreeItemId subcurrid1 = m_tree->AppendItem(currid, + wxT("*** ") + wxString::FromAscii(marker_descr[m]) + wxT(" ***"), + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + m_tree->SetItemFont(subcurrid1, *wxITALIC_FONT); + + // position and length + wxTreeItemId subcurrid2 = m_tree->AppendItem(currid, + wxLongLong(offset).ToString() + wxT(" > ") + wxLongLong(offset + currlen + 1).ToString() + + wxT(", ") + wxString::Format(wxT("%d + 2 (%d)"), currlen, currlen + 2), + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + // give additional info on markers + switch (currmark) { + + ///////// + // SOP // + ///////// + case SOP_VAL: + { + // read packet number + if (m_file->Read(twobytes, 2) != 2) + break; + int packnum = STREAM_TO_UINT16(twobytes, 0); + + image = m_tree->TreeCtrlIcon_File; + imageSel = image + 1; + + wxTreeItemId subcurrid3 = m_tree->AppendItem(currid, + wxString::Format(wxT("Pack. no. %d"), packnum), + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + inside_sop = 1; + }; + break; + +#ifdef USE_JPWL + ///////// + // RED // + ///////// + case RED_VAL: + { + if (m_file->Read(onebyte, 1) != 1) + break; + unsigned char pred = onebyte[0]; + + image = m_tree->TreeCtrlIcon_File; + imageSel = image + 1; + + wxString address[] = { + wxT("Packet addressing"), + wxT("Byte-range addressing"), + wxT("Packet-range addressing"), + wxT("Reserved") + }; + + wxTreeItemId subcurrid = m_tree->AppendItem(currid, + address[(pred & 0xC0) >> 6], + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + subcurrid = m_tree->AppendItem(currid, + wxString::Format(wxT("%d bytes range"), (((pred & 0x02) >> 1) + 1) * 2), + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + subcurrid = m_tree->AppendItem(currid, + pred & 0x01 ? wxT("Errors/erasures in codestream") : wxT("Error free codestream"), + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + subcurrid = m_tree->AppendItem(currid, + wxString::Format(wxT("Residual corruption level: %d"), (pred & 0x38) >> 3), + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + } + break; + + ///////// + // ESD // + ///////// + case ESD_VAL: + { + unsigned short int cesd; + if (csiz < 257) { + if (m_file->Read(onebyte, 1) != 1) + break; + cesd = onebyte[0]; + } else { + if (m_file->Read(twobytes, 2) != 2) + break; + cesd = STREAM_TO_UINT16(twobytes, 0); + } + + if (m_file->Read(onebyte, 1) != 1) + break; + unsigned char pesd = onebyte[0]; + + image = m_tree->TreeCtrlIcon_File; + imageSel = image + 1; + + wxTreeItemId subcurrid = m_tree->AppendItem(currid, + pesd & 0x01 ? wxT("Comp. average") : wxString::Format(wxT("Comp. no. %d"), cesd), + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + wxString meth[] = { + wxT("Relative error sensitivity"), + wxT("MSE"), + wxT("MSE reduction"), + wxT("PSNR"), + wxT("PSNR increase"), + wxT("MAXERR (absolute peak error)"), + wxT("TSE (total squared error)"), + wxT("Reserved") + }; + + subcurrid = m_tree->AppendItem(currid, + meth[(pesd & 0x38) >> 3], + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + wxString address[] = { + wxT("Packet addressing"), + wxT("Byte-range addressing"), + wxT("Packet-range addressing"), + wxT("Reserved") + }; + + subcurrid = m_tree->AppendItem(currid, + address[(pesd & 0xC0) >> 6], + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + subcurrid = m_tree->AppendItem(currid, + wxString::Format(wxT("%d bytes/value, %d bytes range"), ((pesd & 0x04) >> 2) + 1, (((pesd & 0x02) >> 1) + 1) * 2), + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + } + break; + + ///////// + // EPC // + ///////// + case EPC_VAL: + { + if (m_file->Read(twobytes, 2) != 2) + break; + unsigned short int pcrc = STREAM_TO_UINT16(twobytes, 0); + + if (m_file->Read(fourbytes, 4) != 4) + break; + unsigned long int dl = STREAM_TO_UINT32(fourbytes, 0); + + if (m_file->Read(onebyte, 1) != 1) + break; + unsigned char pepc = onebyte[0]; + + image = m_tree->TreeCtrlIcon_File; + imageSel = image + 1; + + wxTreeItemId subcurrid = m_tree->AppendItem(currid, + wxString::Format(wxT("CRC-16 = 0x%x"), pcrc), + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + subcurrid = m_tree->AppendItem(currid, + wxString::Format(wxT("Tot. length = %d"), dl), + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + subcurrid = m_tree->AppendItem(currid, + wxString::Format(wxT("%s%s%s%s"), + pepc & 0x10 ? wxT("ESD, ") : wxT(""), + pepc & 0x20 ? wxT("RED, ") : wxT(""), + pepc & 0x40 ? wxT("EPB, ") : wxT(""), + pepc & 0x80 ? wxT("Info") : wxT("") + ), + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + } + break; + + ///////// + // EPB // + ///////// + case EPB_VAL: + { + if (m_file->Read(onebyte, 1) != 1) + break; + unsigned char depb = onebyte[0]; + + if (m_file->Read(fourbytes, 4) != 4) + break; + unsigned long int ldpepb = STREAM_TO_UINT32(fourbytes, 0); + + if (m_file->Read(fourbytes, 4) != 4) + break; + unsigned long int pepb = STREAM_TO_UINT32(fourbytes, 0); + + image = m_tree->TreeCtrlIcon_File; + imageSel = image + 1; + + wxTreeItemId subcurrid = m_tree->AppendItem(currid, + wxString::Format(wxT("No. %d, %slatest, %spacked"), + depb & 0x3F, + depb & 0x40 ? wxT("") : wxT("not "), + depb & 0x80 ? wxT("") : wxT("un")), + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + subcurrid = m_tree->AppendItem(currid, + wxString::Format(wxT("%d bytes protected"), ldpepb), + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + if (pepb == 0x00000000) + + subcurrid = m_tree->AppendItem(currid, + wxT("Predefined codes"), + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + else if ((pepb >= 0x10000000) && (pepb <= 0x1FFFFFFF)) { + + wxString text = wxT("CRC code"); + if (pepb == 0x10000000) + text << wxT(", CCITT (X25) 16 bits"); + else if (pepb == 0x10000001) + text << wxT(", Ethernet 32 bits"); + else + text << wxT(", JPWL RA"); + subcurrid = m_tree->AppendItem(currid, + text, + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + } else if ((pepb >= 0x20000000) && (pepb <= 0x2FFFFFFF)) { + + wxString text; + subcurrid = m_tree->AppendItem(currid, + wxString::Format(wxT("RS code, RS(%d, %d)"), + (pepb & 0x0000FF00) >> 8, + (pepb & 0x000000FF)), + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + } else if ((pepb >= 0x30000000) && (pepb <= 0x3FFFFFFE)) + + subcurrid = m_tree->AppendItem(currid, + wxT("JPWL RA"), + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + else if (pepb == 0xFFFFFFFF) + + subcurrid = m_tree->AppendItem(currid, + wxT("No method"), + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + } + break; +#endif // USE_JPWL + +#ifdef USE_JPSEC + case SEC_VAL: + { + + } + break; +#endif // USE_JPSEC + + ///////// + // SIZ // + ///////// + case SIZ_VAL: + { + int c; + + if (m_file->Read(twobytes, 2) != 2) + break; + unsigned short int rsiz = STREAM_TO_UINT16(twobytes, 0); + + if (m_file->Read(fourbytes, 4) != 4) + break; + unsigned long int xsiz = STREAM_TO_UINT32(fourbytes, 0); + + if (m_file->Read(fourbytes, 4) != 4) + break; + unsigned long int ysiz = STREAM_TO_UINT32(fourbytes, 0); + + if (m_file->Read(fourbytes, 4) != 4) + break; + unsigned long int xosiz = STREAM_TO_UINT32(fourbytes, 0); + + if (m_file->Read(fourbytes, 4) != 4) + break; + unsigned long int yosiz = STREAM_TO_UINT32(fourbytes, 0); + + if (m_file->Read(fourbytes, 4) != 4) + break; + unsigned long int xtsiz = STREAM_TO_UINT32(fourbytes, 0); + this->m_tree->m_childframe->m_twidth = xtsiz; + + if (m_file->Read(fourbytes, 4) != 4) + break; + unsigned long int ytsiz = STREAM_TO_UINT32(fourbytes, 0); + this->m_tree->m_childframe->m_theight = ytsiz; + + if (m_file->Read(fourbytes, 4) != 4) + break; + unsigned long int xtosiz = STREAM_TO_UINT32(fourbytes, 0); + this->m_tree->m_childframe->m_tx = xtosiz; + + if (m_file->Read(fourbytes, 4) != 4) + break; + unsigned long int ytosiz = STREAM_TO_UINT32(fourbytes, 0); + this->m_tree->m_childframe->m_ty = ytosiz; + + if (m_file->Read(twobytes, 2) != 2) + break; + csiz = STREAM_TO_UINT16(twobytes, 0); + + bool equaldepth = true, equalsize = true; + unsigned char *ssiz = new unsigned char(csiz); + unsigned char *xrsiz = new unsigned char(csiz); + unsigned char *yrsiz = new unsigned char(csiz); + + for (c = 0; c < csiz; c++) { + + if (m_file->Read(&ssiz[c], 1) != 1) + break; + + if (c > 0) + equaldepth = equaldepth && (ssiz[c] == ssiz[c - 1]); + + if (m_file->Read(&xrsiz[c], 1) != 1) + break; + + if (m_file->Read(&yrsiz[c], 1) != 1) + break; + + if (c > 0) + equalsize = equalsize && (xrsiz[c] == xrsiz[c - 1]) && (yrsiz[c] == yrsiz[c - 1]) ; + + } + + if (equaldepth && equalsize) + wxTreeItemId subcurrid3 = m_tree->AppendItem(currid, + wxString::Format(wxT("I: %dx%d (%d, %d), %d c., %d%s bpp"), + xsiz, ysiz, + xosiz, yosiz, + csiz, ((ssiz[0] & 0x7F) + 1), + (ssiz[0] & 0x80) ? wxT("s") : wxT("u")), + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + else + wxTreeItemId subcurrid3 = m_tree->AppendItem(currid, + wxString::Format(wxT("I: %dx%d (%d, %d), %d c."), + xsiz, ysiz, + xosiz, yosiz, + csiz), + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + wxTreeItemId subcurrid3 = m_tree->AppendItem(currid, + wxString::Format(wxT("T: %dx%d (%d, %d)"), + xtsiz, ytsiz, + xtosiz, ytosiz), + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + image = m_tree->TreeCtrlIcon_Folder; + imageSel = image + 1; + + wxTreeItemId subcurrid4 = m_tree->AppendItem(currid, + wxT("Components"), + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + image = m_tree->TreeCtrlIcon_File; + imageSel = image + 1; + + for (c = 0; c < csiz; c++) { + + wxTreeItemId subcurrid5 = m_tree->AppendItem(subcurrid4, + wxString::Format(wxT("#%d: %dx%d, %d%s bpp"), + c, + xsiz/xrsiz[c], ysiz/yrsiz[c], + ((ssiz[c] & 0x7F) + 1), + (ssiz[c] & 0x80) ? wxT("s") : wxT("u")), + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + } + + }; + break; + + ///////// + // SOT // + ///////// + case SOT_VAL: + { + if (m_file->Read(twobytes, 2) != 2) + break; + unsigned short int isot = STREAM_TO_UINT16(twobytes, 0); + + if (m_file->Read(fourbytes, 4) != 4) + break; + unsigned long int psot = STREAM_TO_UINT32(fourbytes, 0); + + if (m_file->Read(onebyte, 1) != 1) + break; + unsigned char tpsot = onebyte[0]; + + if (m_file->Read(onebyte, 1) != 1) + break; + unsigned char tnsot = onebyte[0]; + + wxTreeItemId subcurrid3 = m_tree->AppendItem(currid, + wxString::Format(wxT("tile %d, psot = %d, part %d of %d"), isot, psot, tpsot, tnsot), + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + lastPsot = psot; + lastsotpos = offset; + inside_sod = 0; + }; + break; + + ///////// + // COC // + ///////// + case COC_VAL: + { + unsigned short int ccoc; + if (csiz < 257) { + if (m_file->Read(onebyte, 1) != 1) + break; + ccoc = onebyte[0]; + } else { + if (m_file->Read(twobytes, 2) != 2) + break; + ccoc = STREAM_TO_UINT16(twobytes, 0); + } + + if (m_file->Read(onebyte, 1) != 1) + break; + unsigned char scoc = onebyte[0]; + + wxTreeItemId subcurrid = m_tree->AppendItem(currid, + wxString::Format(wxT("Comp. no. %d"), ccoc), + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + wxString text; + if (scoc & 0x01) + text << wxT("Partitioned entropy coder"); + else + text << wxT("Unpartitioned entropy coder"); + + subcurrid = m_tree->AppendItem(currid, + text, + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + if (m_file->Read(onebyte, 1) != 1) + break; + unsigned char decomplevs = onebyte[0]; + + if (m_file->Read(onebyte, 1) != 1) + break; + unsigned char cbswidth = onebyte[0]; + + if (m_file->Read(onebyte, 1) != 1) + break; + unsigned char cbsheight = onebyte[0]; + + if (m_file->Read(onebyte, 1) != 1) + break; + unsigned char cbstyle = onebyte[0]; + + if (m_file->Read(onebyte, 1) != 1) + break; + unsigned char transform = onebyte[0]; + + subcurrid = m_tree->AppendItem(currid, + wxString::Format(wxT("%d levels (%d resolutions)"), decomplevs, decomplevs + 1), + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + if (transform & 0x01) + text = wxT("5-3 reversible wavelet"); + else + text = wxT("9-7 irreversible wavelet"); + subcurrid = m_tree->AppendItem(currid, + text, + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + subcurrid = m_tree->AppendItem(currid, + wxString::Format(wxT("Code-blocks: %dx%d"), 1 << ((cbswidth & 0x0F) + 2), 1 << ((cbsheight & 0x0F) + 2)), + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + image = m_tree->TreeCtrlIcon_Folder; + imageSel = image + 1; + + wxTreeItemId subcurrid3 = m_tree->AppendItem(currid, + wxT("Coding styles"), + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + image = m_tree->TreeCtrlIcon_File; + imageSel = image + 1; + + if (cbstyle & 0x01) + text = wxT("Selective arithmetic coding bypass"); + else + text = wxT("No selective arithmetic coding bypass"); + wxTreeItemId subcurrid4 = m_tree->AppendItem(subcurrid3, + text, + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + if (cbstyle & 0x02) + text = wxT("Reset context probabilities on coding pass boundaries"); + else + text = wxT("No reset of context probabilities on coding pass boundaries"); + subcurrid4 = m_tree->AppendItem(subcurrid3, + text, + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + if (cbstyle & 0x04) + text = wxT("Termination on each coding passs"); + else + text = wxT("No termination on each coding pass"); + subcurrid4 = m_tree->AppendItem(subcurrid3, + text, + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + if (cbstyle & 0x08) + text = wxT("Vertically stripe causal context"); + else + text = wxT("No vertically stripe causal context"); + subcurrid4 = m_tree->AppendItem(subcurrid3, + text, + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + if (cbstyle & 0x10) + text = wxT("Predictable termination"); + else + text = wxT("No predictable termination"); + subcurrid4 = m_tree->AppendItem(subcurrid3, + text, + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + if (cbstyle & 0x20) + text = wxT("Segmentation symbols are used"); + else + text = wxT("No segmentation symbols are used"); + subcurrid4 = m_tree->AppendItem(subcurrid3, + text, + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + } + break; + + ///////// + // COD // + ///////// + case COD_VAL: + { + if (m_file->Read(onebyte, 1) != 1) + break; + unsigned char scod = onebyte[0]; + + wxString text; + + if (scod & 0x01) + text << wxT("Partitioned entropy coder"); + else + text << wxT("Unpartitioned entropy coder"); + + wxTreeItemId subcurrid3 = m_tree->AppendItem(currid, + text, + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + text = wxT(""); + if (scod & 0x02) + text << wxT("Possible SOPs"); + else + text << wxT("No SOPs"); + + if (scod & 0x04) + text << wxT(", possible EPHs"); + else + text << wxT(", no EPHs"); + + subcurrid3 = m_tree->AppendItem(currid, + text, + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + if (m_file->Read(onebyte, 1) != 1) + break; + unsigned char progord = onebyte[0]; + + if (m_file->Read(twobytes, 2) != 2) + break; + unsigned short int numlayers = STREAM_TO_UINT16(twobytes, 0); + + if (m_file->Read(onebyte, 1) != 1) + break; + unsigned char mctransform = onebyte[0]; + + if (m_file->Read(onebyte, 1) != 1) + break; + unsigned char decomplevs = onebyte[0]; + + if (m_file->Read(onebyte, 1) != 1) + break; + unsigned char cbswidth = onebyte[0]; + + if (m_file->Read(onebyte, 1) != 1) + break; + unsigned char cbsheight = onebyte[0]; + + if (m_file->Read(onebyte, 1) != 1) + break; + unsigned char cbstyle = onebyte[0]; + + if (m_file->Read(onebyte, 1) != 1) + break; + unsigned char transform = onebyte[0]; + + subcurrid3 = m_tree->AppendItem(currid, + wxString::Format(wxT("%d levels (%d resolutions)"), decomplevs, decomplevs + 1), + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + text = wxT(""); + switch (progord) { + case (0): + text << wxT("LRCP"); + break; + case (1): + text << wxT("RLCP"); + break; + case (2): + text << wxT("LRCP"); + break; + case (3): + text << wxT("RPCL"); + break; + case (4): + text << wxT("CPRL"); + break; + default: + text << wxT("unknown progression"); + break; + } + text << wxString::Format(wxT(", %d layers"), numlayers); + if (transform & 0x01) + text << wxT(", 5-3 rev."); + else + text << wxT(", 9-7 irr."); + subcurrid3 = m_tree->AppendItem(currid, + text, + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + subcurrid3 = m_tree->AppendItem(currid, + wxString::Format(wxT("Code-blocks: %dx%d"), 1 << ((cbswidth & 0x0F) + 2), 1 << ((cbsheight & 0x0F) + 2)), + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + switch (mctransform) { + case (0): + { + text = wxT("No MCT"); + } + break; + case (1): + { + text = wxT("Reversible MCT on 0, 1, 2"); + } + break; + case (2): + { + text = wxT("Irreversible MCT on 0, 1, 2"); + } + break; + default: + { + text = wxT("Unknown"); + } + break; + }; + subcurrid3 = m_tree->AppendItem(currid, + text, + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + + image = m_tree->TreeCtrlIcon_Folder; + imageSel = image + 1; + + subcurrid3 = m_tree->AppendItem(currid, + wxT("Coding styles"), + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + image = m_tree->TreeCtrlIcon_File; + imageSel = image + 1; + + if (cbstyle & 0x01) + text = wxT("Selective arithmetic coding bypass"); + else + text = wxT("No selective arithmetic coding bypass"); + wxTreeItemId subcurrid4 = m_tree->AppendItem(subcurrid3, + text, + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + if (cbstyle & 0x02) + text = wxT("Reset context probabilities on coding pass boundaries"); + else + text = wxT("No reset of context probabilities on coding pass boundaries"); + subcurrid4 = m_tree->AppendItem(subcurrid3, + text, + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + if (cbstyle & 0x04) + text = wxT("Termination on each coding passs"); + else + text = wxT("No termination on each coding pass"); + subcurrid4 = m_tree->AppendItem(subcurrid3, + text, + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + if (cbstyle & 0x08) + text = wxT("Vertically stripe causal context"); + else + text = wxT("No vertically stripe causal context"); + subcurrid4 = m_tree->AppendItem(subcurrid3, + text, + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + if (cbstyle & 0x10) + text = wxT("Predictable termination"); + else + text = wxT("No predictable termination"); + subcurrid4 = m_tree->AppendItem(subcurrid3, + text, + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + if (cbstyle & 0x20) + text = wxT("Segmentation symbols are used"); + else + text = wxT("No segmentation symbols are used"); + subcurrid4 = m_tree->AppendItem(subcurrid3, + text, + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + }; + break; + + ///////// + // QCC // + ///////// + case QCC_VAL: + { + unsigned short int cqcc; + if (csiz < 257) { + if (m_file->Read(onebyte, 1) != 1) + break; + cqcc = onebyte[0]; + } else { + if (m_file->Read(twobytes, 2) != 2) + break; + cqcc = STREAM_TO_UINT16(twobytes, 0); + } + + wxTreeItemId subcurrid = m_tree->AppendItem(currid, + wxString::Format(wxT("Comp. no. %d"), cqcc), + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + if (m_file->Read(onebyte, 1) != 1) + break; + unsigned char sqcc = onebyte[0]; + + wxString text; + switch (sqcc & 0x1F) { + case (0): + text = wxT("No quantization"); + break; + case (1): + text = wxT("Scalar implicit"); + break; + case (2): + text = wxT("Scalar explicit"); + break; + default: + text = wxT("Unknown"); + break; + } + text << wxString::Format(wxT(", %d guard bits"), (sqcc & 0xE0) >> 5); + wxTreeItemId subcurrid3 = m_tree->AppendItem(currid, + text, + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + } + break; + + ///////// + // QCD // + ///////// + case QCD_VAL: + { + if (m_file->Read(onebyte, 1) != 1) + break; + unsigned char sqcd = onebyte[0]; + + wxString text; + switch (sqcd & 0x1F) { + case (0): + text = wxT("No quantization"); + break; + case (1): + text = wxT("Scalar implicit"); + break; + case (2): + text = wxT("Scalar explicit"); + break; + default: + text = wxT("Unknown"); + break; + } + text << wxString::Format(wxT(", %d guard bits"), (sqcd & 0xE0) >> 5); + wxTreeItemId subcurrid3 = m_tree->AppendItem(currid, + text, + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + }; + break; + + ///////// + // COM // + ///////// + case COM_VAL: + { + #define showlen 25 + char comment[showlen]; + wxString comments; + + if (m_file->Read(twobytes, 2) != 2) + break; + unsigned short int rcom = STREAM_TO_UINT16(twobytes, 0); + + wxString text; + if (rcom == 0) + text = wxT("Binary values"); + else if (rcom == 1) + text = wxT("ISO 8859-1 (latin-1) values"); + else if (rcom < 65535) + text = wxT("Reserved for registration"); + else + text = wxT("Reserved for extension"); + wxTreeItemId subcurrid3 = m_tree->AppendItem(currid, + text, + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + if (m_file->Read(comment, showlen) != showlen) + break; + comments = wxString::FromAscii(comment).Truncate(wxMin(showlen, currlen - 4)); + if ((currlen - 4) > showlen) + comments << wxT("..."); + subcurrid3 = m_tree->AppendItem(currid, + comments, + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + }; + break; + + ///////// + // TLM // + ///////// + case TLM_VAL: + { + if (m_file->Read(onebyte, 1) != 1) + break; + unsigned char ztlm = onebyte[0]; + + if (m_file->Read(onebyte, 1) != 1) + break; + unsigned char stlm = onebyte[0]; + + image = m_tree->TreeCtrlIcon_File; + imageSel = image + 1; + + wxTreeItemId subcurrid3 = m_tree->AppendItem(currid, + wxString::Format(wxT("TLM #%d"), ztlm), + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + subcurrid3 = m_tree->AppendItem(currid, + wxString::Format(wxT("%d bits/index, %d bits/length"), + 8 * ((stlm & 0x30) >> 4), 16 + 16 * ((stlm & 0x40) >> 6)), + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + int n, numparts; + + numparts = (currlen - 2) / ( ((stlm & 0x30) >> 4) + 2 + 2 * ((stlm & 0x40) >> 6)); + + image = m_tree->TreeCtrlIcon_Folder; + imageSel = image + 1; + + subcurrid3 = m_tree->AppendItem(currid, + wxT("Tile parts"), + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + image = m_tree->TreeCtrlIcon_File; + imageSel = image + 1; + + for (n = 0; n < numparts; n++) { + + unsigned short int ttlm; + unsigned long int ptlm; + + switch (((stlm & 0x30) >> 4)) { + + case 0: + ttlm = 0; + break; + + case 1: + if (m_file->Read(onebyte, 1) != 1) + break; + ttlm = onebyte[0]; + break; + + case 2: + if (m_file->Read(twobytes, 2) != 2) + break; + ttlm = STREAM_TO_UINT16(twobytes, 0); + break; + + } + + switch (((stlm & 0x40) >> 6)) { + + case 0: + if (m_file->Read(twobytes, 2) != 2) + break; + ptlm = STREAM_TO_UINT16(twobytes, 0); + break; + + case 1: + if (m_file->Read(fourbytes, 4) != 4) + break; + ptlm = STREAM_TO_UINT32(fourbytes, 0); + break; + + } + + wxTreeItemId subcurrid4 = m_tree->AppendItem(subcurrid3, + wxString::Format(wxT("Tile %d: %d bytes"), ttlm, ptlm), + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + } + + } + break; + + ///////// + // POD // + ///////// + case POD_VAL: + { + int n, numchanges; + + if (csiz < 257) + numchanges = (currlen - 2) / 7; + else + numchanges = (currlen - 2) / 9; + + for (n = 0; n < numchanges; n++) { + + image = m_tree->TreeCtrlIcon_Folder; + imageSel = image + 1; + + wxTreeItemId subcurrid3 = m_tree->AppendItem(currid, + wxString::Format(wxT("Change #%d"), n), + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + if (m_file->Read(onebyte, 1) != 1) + break; + unsigned char rspod = onebyte[0]; + + unsigned short int cspod; + if (csiz < 257) { + if (m_file->Read(onebyte, 1) != 1) + break; + cspod = onebyte[0]; + } else { + if (m_file->Read(twobytes, 2) != 2) + break; + cspod = STREAM_TO_UINT16(twobytes, 0); + } + + if (m_file->Read(twobytes, 2) != 2) + break; + unsigned short int lyepod = STREAM_TO_UINT16(twobytes, 0); + + if (m_file->Read(onebyte, 1) != 1) + break; + unsigned char repod = onebyte[0]; + + unsigned short int cepod; + if (csiz < 257) { + if (m_file->Read(onebyte, 1) != 1) + break; + cepod = onebyte[0]; + } else { + if (m_file->Read(twobytes, 2) != 2) + break; + cepod = STREAM_TO_UINT16(twobytes, 0); + } + + if (m_file->Read(onebyte, 1) != 1) + break; + unsigned char ppod = onebyte[0]; + + image = m_tree->TreeCtrlIcon_File; + imageSel = image + 1; + + wxTreeItemId subcurrid4 = m_tree->AppendItem(subcurrid3, + wxString::Format(wxT("%d <= Resolution < %d"), rspod, repod), + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + subcurrid4 = m_tree->AppendItem(subcurrid3, + wxString::Format(wxT("%d <= Component < %d"), cspod, cepod), + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + subcurrid4 = m_tree->AppendItem(subcurrid3, + wxString::Format(wxT("0 <= Layer < %d"), lyepod), + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + wxString text = wxT(""); + switch (ppod) { + case (0): + text << wxT("LRCP"); + break; + case (1): + text << wxT("RLCP"); + break; + case (2): + text << wxT("LRCP"); + break; + case (3): + text << wxT("RPCL"); + break; + case (4): + text << wxT("CPRL"); + break; + default: + text << wxT("unknown progression"); + break; + } + subcurrid4 = m_tree->AppendItem(subcurrid3, + text, + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + } + + } + break; + + ///////// + // SOD // + ///////// + case SOD_VAL: + { + inside_sod = 1; + }; + break; + + default: + break; + + } + + // increment number of markers + if (nmarks++ >= maxmarks) { + WriteText(wxT("Maximum amount of markers exceeded")); + break; + } + + // advance position + OPJ_ADVANCE(currlen + 2); + } + + WriteText(wxT("Search finished")); +} diff --git a/applications/OPJViewer/source/wxjp2parser.cpp b/applications/OPJViewer/source/wxjp2parser.cpp index 6e89390a..182def8b 100644 --- a/applications/OPJViewer/source/wxjp2parser.cpp +++ b/applications/OPJViewer/source/wxjp2parser.cpp @@ -1,1116 +1,1116 @@ -/* - * Copyright (c) 2007, Digital Signal Processing Laboratory, Università degli studi di Perugia (UPG), Italy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are 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. - */ -#include "OPJViewer.h" - -/* defines */ -#define SHORT_DESCR_LEN 32 -#define LONG_DESCR_LEN 256 - -/* enumeration for file formats */ -#define J2FILENUM 4 -typedef enum { - - JP2_FILE, - J2K_FILE, - MJ2_FILE, - UNK_FILE - -} j2filetype; - -/* enumeration for the box types */ -#define j22boxNUM 23 -typedef enum { - - FILE_BOX, - JP_BOX, - FTYP_BOX, - JP2H_BOX, - IHDR_BOX, - COLR_BOX, - JP2C_BOX, - JP2I_BOX, - XML_BOX, - UUID_BOX, - UINF_BOX, - MOOV_BOX, - MVHD_BOX, - TRAK_BOX, - TKHD_BOX, - MDIA_BOX, - MDHD_BOX, - HDLR_BOX, - MINF_BOX, - VMHD_BOX, - STBL_BOX, - STSD_BOX, - STSZ_BOX, - MJP2_BOX, - MDAT_BOX, - ANY_BOX, - UNK_BOX - -} j22boxtype; - -/* the box structure itself */ -struct boxdef { - - char value[5]; /* hexadecimal value/string*/ - char name[SHORT_DESCR_LEN]; /* short description */ - char descr[LONG_DESCR_LEN]; /* long description */ - int sbox; /* is it a superbox? */ - int req[J2FILENUM]; /* mandatory box */ - j22boxtype ins; /* contained in box... */ - -}; - - -/* jp2 family box signatures */ -#define FILE_SIGN "" -#define JP_SIGN "jP\040\040" -#define FTYP_SIGN "ftyp" -#define JP2H_SIGN "jp2h" -#define IHDR_SIGN "ihdr" -#define COLR_SIGN "colr" -#define JP2C_SIGN "jp2c" -#define JP2I_SIGN "jp2i" -#define XML_SIGN "xml\040" -#define UUID_SIGN "uuid" -#define UINF_SIGN "uinf" -#define MOOV_SIGN "moov" -#define MVHD_SIGN "mvhd" -#define TRAK_SIGN "trak" -#define TKHD_SIGN "tkhd" -#define MDIA_SIGN "mdia" -#define MDHD_SIGN "mdhd" -#define HDLR_SIGN "hdlr" -#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 "" -#define UNK_SIGN "" - -/* the possible boxes */ -struct boxdef j22box[] = -{ -/* sign */ {FILE_SIGN, -/* short */ "placeholder for nothing", -/* long */ "Nothing to say", -/* sbox */ 0, -/* req */ {1, 1, 1}, -/* ins */ FILE_BOX}, - -/* sign */ {JP_SIGN, -/* short */ "JPEG 2000 Signature box", -/* long */ "This box uniquely identifies the file as being part of the JPEG 2000 family of files", -/* sbox */ 0, -/* req */ {1, 1, 1}, -/* ins */ FILE_BOX}, - -/* sign */ {FTYP_SIGN, -/* short */ "File Type box", -/* long */ "This box specifies file type, version and compatibility information, including specifying if this file " - "is a conforming JP2 file or if it can be read by a conforming JP2 reader", -/* sbox */ 0, -/* req */ {1, 1, 1}, -/* ins */ FILE_BOX}, - -/* sign */ {JP2H_SIGN, -/* short */ "JP2 Header box", -/* long */ "This box contains a series of boxes that contain header-type information about the file", -/* sbox */ 1, -/* req */ {1, 1, 1}, -/* ins */ FILE_BOX}, - -/* sign */ {IHDR_SIGN, -/* short */ "Image Header box", -/* long */ "This box specifies the size of the image and other related fields", -/* sbox */ 0, -/* req */ {1, 1, 1}, -/* ins */ JP2H_BOX}, - -/* sign */ {COLR_SIGN, -/* short */ "Colour Specification box", -/* long */ "This box specifies the colourspace of the image", -/* sbox */ 0, -/* req */ {1, 1, 1}, -/* ins */ JP2H_BOX}, - -/* sign */ {JP2C_SIGN, -/* short */ "Contiguous Codestream box", -/* long */ "This box contains the codestream as defined by Annex A", -/* sbox */ 0, -/* req */ {1, 1, 1}, -/* ins */ FILE_BOX}, - -/* sign */ {JP2I_SIGN, -/* short */ "Intellectual Property box", -/* long */ "This box contains intellectual property information about the image", -/* sbox */ 0, -/* req */ {0, 0, 0}, -/* ins */ FILE_BOX}, - -/* sign */ {XML_SIGN, -/* short */ "XML box", -/* long */ "This box provides a tool by which vendors can add XML formatted information to a JP2 file", -/* sbox */ 0, -/* req */ {0, 0, 0}, -/* ins */ FILE_BOX}, - -/* sign */ {UUID_SIGN, -/* short */ "UUID box", -/* long */ "This box provides a tool by which vendors can add additional information to a file " - "without risking conflict with other vendors", -/* sbox */ 0, -/* req */ {0, 0, 0}, -/* ins */ FILE_BOX}, - -/* sign */ {UINF_SIGN, -/* short */ "UUID Info box", -/* long */ "This box provides a tool by which a vendor may provide access to additional information associated with a UUID", -/* sbox */ 0, -/* req */ {0, 0, 0}, -/* ins */ FILE_BOX}, - -/* sign */ {MOOV_SIGN, -/* short */ "Movie box", -/* long */ "This box contains the media data. In video tracks, this box would contain JPEG2000 video frames", -/* sbox */ 1, -/* req */ {1, 1, 1}, -/* ins */ FILE_BOX}, - -/* sign */ {MVHD_SIGN, -/* short */ "Movie Header box", -/* long */ "This box defines overall information which is media-independent, and relevant to the entire presentation " - "considered as a whole", -/* sbox */ 0, -/* req */ {1, 1, 1}, -/* ins */ MOOV_BOX}, - -/* sign */ {TRAK_SIGN, -/* short */ "Track box", -/* long */ "This is a container box for a single track of a presentation. A presentation may consist of one or more tracks", -/* sbox */ 1, -/* req */ {1, 1, 1}, -/* ins */ MOOV_BOX}, - -/* sign */ {TKHD_SIGN, -/* short */ "Track Header box", -/* long */ "This box specifies the characteristics of a single track. Exactly one Track Header Box is contained in a track", -/* sbox */ 0, -/* req */ {1, 1, 1}, -/* ins */ TRAK_BOX}, - -/* sign */ {MDIA_SIGN, -/* short */ "Media box", -/* long */ "The media declaration container contains all the objects which declare information about the media data " - "within a track", -/* sbox */ 1, -/* req */ {1, 1, 1}, -/* ins */ TRAK_BOX}, - -/* sign */ {MDHD_SIGN, -/* short */ "Media Header box", -/* long */ "The media header declares overall information which is media-independent, and relevant to characteristics " - "of the media in a track", -/* sbox */ 0, -/* req */ {1, 1, 1}, -/* ins */ MDIA_BOX}, - -/* sign */ {HDLR_SIGN, -/* short */ "Handler Reference box", -/* long */ "This box within a Media Box declares the process by which the media-data in the track may be presented, " - "and thus, the nature of the media in a track", -/* sbox */ 0, -/* req */ {1, 1, 1}, -/* ins */ MDIA_BOX}, - -/* sign */ {MINF_SIGN, -/* short */ "Media Information box", -/* long */ "This box contains all the objects which declare characteristic information of the media in the track", -/* sbox */ 1, -/* 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", -/* sbox */ 1, -/* req */ {1, 1, 1}, -/* ins */ MINF_BOX}, - -/* sign */ {STSD_SIGN, -/* 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 " - "information needed for that coding", -/* sbox */ 0, -/* req */ {1, 1, 1}, -/* ins */ MINF_BOX}, - -/* sign */ {MDAT_SIGN, -/* short */ "Media Data box", -/* long */ "The meta-data for a presentation is stored in the single Movie Box which occurs at the top-level of a file", -/* sbox */ 1, -/* req */ {1, 1, 1}, -/* ins */ FILE_BOX}, - -/* sign */ {ANY_SIGN, -/* short */ "Any box", -/* long */ "All the existing boxes", -/* sbox */ 0, -/* req */ {0, 0, 0}, -/* ins */ FILE_BOX}, - -/* sign */ {UNK_SIGN, -/* short */ "Unknown Type box", -/* long */ "The signature is not recognised to be that of an existing box", -/* sbox */ 0, -/* req */ {0, 0, 0}, -/* ins */ ANY_BOX} - -}; - - -/* macro functions */ -/* From little endian to big endian, 2 and 4 bytes */ -#define BYTE_SWAP2(X) ((X & 0x00FF) << 8) | ((X & 0xFF00) >> 8) -#define BYTE_SWAP4(X) ((X & 0x000000FF) << 24) | ((X & 0x0000FF00) << 8) | ((X & 0x00FF0000) >> 8) | ((X & 0xFF000000) >> 24) - -#ifdef __WXGTK__ -#define BYTE_SWAP8(X) ((X & 0x00000000000000FFULL) << 56) | ((X & 0x000000000000FF00ULL) << 40) | \ - ((X & 0x0000000000FF0000ULL) << 24) | ((X & 0x00000000FF000000ULL) << 8) | \ - ((X & 0x000000FF00000000ULL) >> 8) | ((X & 0x0000FF0000000000ULL) >> 24) | \ - ((X & 0x00FF000000000000ULL) >> 40) | ((X & 0xFF00000000000000ULL) >> 56) -#else -#define BYTE_SWAP8(X) ((X & 0x00000000000000FF) << 56) | ((X & 0x000000000000FF00) << 40) | \ - ((X & 0x0000000000FF0000) << 24) | ((X & 0x00000000FF000000) << 8) | \ - ((X & 0x000000FF00000000) >> 8) | ((X & 0x0000FF0000000000) >> 24) | \ - ((X & 0x00FF000000000000) >> 40) | ((X & 0xFF00000000000000) >> 56) -#endif - -/* From codestream to int values */ -#define STREAM_TO_UINT32(C, P) (((unsigned long int) (C)[(P) + 0] << 24) + \ - ((unsigned long int) (C)[(P) + 1] << 16) + \ - ((unsigned long int) (C)[(P) + 2] << 8) + \ - ((unsigned long int) (C)[(P) + 3] << 0)) - -#define STREAM_TO_UINT16(C, P) (((unsigned long int) (C)[(P) + 0] << 8) + \ - ((unsigned long int) (C)[(P) + 1] << 0)) - -#define OPJREAD_LONG(F,L,N) { \ - if (F->Read(fourbytes, 4) < 4) { \ - wxLogMessage(wxT("Problem reading " N " from the file (file ended?)")); \ - return -1; \ - }; \ - L = STREAM_TO_UINT32(fourbytes, 0); \ - } - -/* handling functions */ -#define ITEM_PER_ROW 10 - -//#define indprint if (0) printf("%.*s", 2 * level + 9, indent), printf -char indent[] = " " - " " - " " - " "; - -void indprint(wxString printout, int level) -{ - wxLogMessage(/*wxString::Format(wxT("%.*s"), 2 * level + 9, indent) + */printout); -} - -/* Box handler function */ -int OPJParseThread::box_handler_function(int boxtype, wxFile *fileid, wxFileOffset filepoint, wxFileOffset filelimit, - wxTreeItemId parentid, int level, char *scansign, unsigned long int *scanpoint) -{ - switch ((j22boxtype) boxtype) { - - - /* JPEG 2000 Signature box */ - case (JP_BOX): { - - unsigned long int checkdata = 0; - fileid->Read(&checkdata, sizeof(unsigned long int)); - checkdata = BYTE_SWAP4(checkdata); - - // add info - wxTreeItemId currid = m_tree->AppendItem(parentid, - wxString::Format(wxT("Check data: %X -> %s"), checkdata, (checkdata == 0x0D0A870A) ? wxT("OK") : wxT("KO")), - m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1, - new OPJMarkerData(wxT("INFO")) - ); - - }; - break; - - - /* JPEG 2000 codestream box */ - case (JP2C_BOX): { - - // add info - wxTreeItemId currid = m_tree->AppendItem(parentid, - wxString(wxT("Codestream")), - m_tree->TreeCtrlIcon_Folder, m_tree->TreeCtrlIcon_Folder + 1, - new OPJMarkerData(wxT("INFO-CSTREAM"), m_tree->m_fname.GetFullPath(), filepoint, filelimit) - ); - - m_tree->SetItemHasChildren(currid); - - // parse the file - //ParseJ2KFile(fileid, filepoint, filelimit, currid); - - }; - break; - - - - - - /* File Type box */ - case (FTYP_BOX): { - - char BR[4], CL[4]; - unsigned long int MinV, numCL, i; - fileid->Read(BR, sizeof(char) * 4); - fileid->Read(&MinV, sizeof(unsigned long int)); - MinV = BYTE_SWAP4(MinV); - numCL = (filelimit - fileid->Tell()) / 4; - - // add info - wxTreeItemId currid = m_tree->AppendItem(parentid, - wxT("Brand/Minor version: ") + - wxString::FromAscii(BR).Truncate(4) + - wxString::Format(wxT("/%d"), MinV), - m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1, - new OPJMarkerData(wxT("INFO")) - ); - - currid = m_tree->AppendItem(parentid, - wxString::Format(wxT("Compatibility list")), - m_tree->TreeCtrlIcon_Folder, m_tree->TreeCtrlIcon_Folder + 1, - new OPJMarkerData(wxT("INFO")) - ); - - for (i = 0; i < numCL; i++) { - fileid->Read(CL, sizeof(char) * 4); - m_tree->AppendItem(currid, - wxString::FromAscii(CL).Truncate(4), - m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1, - new OPJMarkerData(wxT("INFO")) - ); - }; - - }; - break; - - - - /* JP2 Header box */ - case (IHDR_BOX): { - - unsigned long int height, width; - unsigned short int nc; - unsigned char bpc, C, UnkC, IPR; - fileid->Read(&height, sizeof(unsigned long int)); - height = BYTE_SWAP4(height); - fileid->Read(&width, sizeof(unsigned long int)); - width = BYTE_SWAP4(width); - fileid->Read(&nc, sizeof(unsigned short int)); - nc = BYTE_SWAP2(nc); - fileid->Read(&bpc, sizeof(unsigned char)); - fileid->Read(&C, sizeof(unsigned char)); - fileid->Read(&UnkC, sizeof(unsigned char)); - fileid->Read(&IPR, sizeof(unsigned char)); - - // add info - wxTreeItemId currid = m_tree->AppendItem(parentid, - wxString::Format(wxT("Dimensions: %d x %d x %d @ %d bpc"), width, height, nc, bpc + 1), - m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1, - new OPJMarkerData(wxT("INFO")) - ); - - currid = m_tree->AppendItem(parentid, - wxString::Format(wxT("Compression type: %d"), C), - m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1, - new OPJMarkerData(wxT("INFO")) - ); - - currid = m_tree->AppendItem(parentid, - wxString::Format(wxT("Colourspace unknown: %d"), UnkC), - m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1, - new OPJMarkerData(wxT("INFO")) - ); - - currid = m_tree->AppendItem(parentid, - wxString::Format(wxT("Intellectual Property Rights: %d"), IPR), - m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1, - new OPJMarkerData(wxT("INFO")) - ); - - }; - break; - - - - /* Colour Specification box */ - case (COLR_BOX): { - - unsigned char METH, PREC, APPROX; - char methdescr[80], enumcsdescr[80]; - unsigned long int EnumCS; - fileid->Read(&METH, sizeof(unsigned char)); - switch (METH) { - case 1: - strcpy(methdescr, "Enumerated Colourspace"); - break; - case 2: - strcpy(methdescr, "Restricted ICC profile"); - break; - default: - strcpy(methdescr, "Unknown"); - break; - }; - fileid->Read(&PREC, sizeof(unsigned char)); - fileid->Read(&APPROX, sizeof(unsigned char)); - if (METH != 2) { - fileid->Read(&EnumCS, sizeof(unsigned long int)); - EnumCS = BYTE_SWAP4(EnumCS); - switch (EnumCS) { - case 16: - strcpy(enumcsdescr, "sRGB"); - break; - case 17: - strcpy(enumcsdescr, "greyscale"); - break; - case 18: - strcpy(enumcsdescr, "sYCC"); - break; - default: - strcpy(enumcsdescr, "Unknown"); - break; - }; - }; - - // add info - wxTreeItemId currid = m_tree->AppendItem(parentid, - wxString::Format(wxT("Specification method: %d ("), METH) + - wxString::FromAscii(methdescr) + - wxT(")"), - m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1, - new OPJMarkerData(wxT("INFO")) - ); - - currid = m_tree->AppendItem(parentid, - wxString::Format(wxT("Precedence: %d"), PREC), - m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1, - new OPJMarkerData(wxT("INFO")) - ); - - currid = m_tree->AppendItem(parentid, - wxString::Format(wxT("Colourspace approximation: %d"), APPROX), - m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1, - new OPJMarkerData(wxT("INFO")) - ); - - if (METH != 2) - currid = m_tree->AppendItem(parentid, - wxString::Format(wxT("Enumerated colourspace: %d ("), EnumCS) + - wxString::FromAscii(enumcsdescr) + - wxT(")"), - m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1, - new OPJMarkerData(wxT("INFO")) - ); - - if (METH != 1) - currid = m_tree->AppendItem(parentid, - wxString::Format(wxT("ICC profile: there is one")), - m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1, - new OPJMarkerData(wxT("INFO")) - ); - - - }; - break; - - - - - - - /* Movie Header Box */ - case (MVHD_BOX): { - - unsigned long int version, rate, matrix[9], next_track_ID; - unsigned short int volume; - fileid->Read(&version, sizeof(unsigned long int)); - version = BYTE_SWAP4(version); - if (version == 0) { - unsigned long int creation_time, modification_time, timescale, duration; - fileid->Read(&creation_time, sizeof(unsigned long int)); - creation_time = BYTE_SWAP4(creation_time); - fileid->Read(&modification_time, sizeof(unsigned long int)); - modification_time = BYTE_SWAP4(modification_time); - fileid->Read(×cale, sizeof(unsigned long int)); - timescale = BYTE_SWAP4(timescale); - fileid->Read(&duration, sizeof(unsigned long int)); - duration = BYTE_SWAP4(duration); - const long unix_time = creation_time - 2082844800L; - wxTreeItemId currid = m_tree->AppendItem(parentid, - wxString::Format(wxT("Creation time: %u (%.24s)"), creation_time, ctime(&unix_time)), - m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1, - new OPJMarkerData(wxT("INFO")) - ); - const long unix_time1 = modification_time - 2082844800L; - currid = m_tree->AppendItem(parentid, - wxString::Format(wxT("Modification time: %u (%.24s)"), modification_time, ctime(&unix_time1)), - m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1, - new OPJMarkerData(wxT("INFO")) - ); - currid = m_tree->AppendItem(parentid, - wxString::Format(wxT("Timescale: %u (%.6fs)"), timescale, 1.0 / (float) timescale), - m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1, - new OPJMarkerData(wxT("INFO")) - ); - currid = m_tree->AppendItem(parentid, - wxString::Format(wxT("Duration: %u (%.3fs)"), duration, (float) duration / (float) timescale), - m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1, - new OPJMarkerData(wxT("INFO")) - ); - } else { - int8byte creation_time, modification_time, duration; - unsigned long int timescale; - fileid->Read(&creation_time, sizeof(int8byte)); - creation_time = BYTE_SWAP8(creation_time); - 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(int8byte)); - duration = BYTE_SWAP8(duration); - wxTreeItemId currid = m_tree->AppendItem(parentid, - wxString::Format(wxT("Creation time: %u"), creation_time), - m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1, - new OPJMarkerData(wxT("INFO")) - ); - currid = m_tree->AppendItem(parentid, - wxString::Format(wxT("Modification time: %u"), modification_time), - m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1, - new OPJMarkerData(wxT("INFO")) - ); - currid = m_tree->AppendItem(parentid, - wxString::Format(wxT("Timescale: %u"), timescale), - m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1, - new OPJMarkerData(wxT("INFO")) - ); - currid = m_tree->AppendItem(parentid, - wxString::Format(wxT("Duration: %u"), duration), - m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1, - new OPJMarkerData(wxT("INFO")) - ); - }; - fileid->Read(&rate, sizeof(unsigned long int)); - rate = BYTE_SWAP4(rate); - fileid->Read(&volume, sizeof(unsigned short int)); - volume = BYTE_SWAP2(volume); - fileid->Seek(6, wxFromCurrent); - fileid->Read(&matrix, sizeof(unsigned char) * 9); - fileid->Seek(4, wxFromCurrent); - fileid->Read(&next_track_ID, sizeof(unsigned long int)); - next_track_ID = BYTE_SWAP4(next_track_ID); - wxTreeItemId currid = m_tree->AppendItem(parentid, - wxString::Format(wxT("Rate: %d (%d.%d)"), rate, rate >> 16, rate & 0x0000FFFF), - m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1, - new OPJMarkerData(wxT("INFO")) - ); - currid = m_tree->AppendItem(parentid, - wxString::Format(wxT("Volume: %d (%d.%d)"), volume, volume >> 8, volume & 0x00FF), - m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1, - new OPJMarkerData(wxT("INFO")) - ); - currid = m_tree->AppendItem(parentid, - wxString::Format(wxT("Next track ID: %d"), next_track_ID), - m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1, - new OPJMarkerData(wxT("INFO")) - ); - }; - break; - - - /* Sample Description box */ - case (STSD_BOX): { - - unsigned long int version, entry_count; - fileid->Read(&version, sizeof(unsigned long int)); - version = BYTE_SWAP4(version); - fileid->Read(&entry_count, sizeof(unsigned long int)); - entry_count = BYTE_SWAP4(entry_count); - wxTreeItemId currid = m_tree->AppendItem(parentid, - wxString::Format(wxT("Entry count: %d"), entry_count), - m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1, - new OPJMarkerData(wxT("INFO"), m_tree->m_fname.GetFullPath(), filepoint, filelimit) - ); - jpeg2000parse(fileid, filepoint + 8, filelimit, parentid, level + 1, scansign, scanpoint); - }; - 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 (unsigned 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 (")) + - wxString::FromAscii(graphicsdescr) + - wxT(")"), - 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): { - - unsigned short int height, width, depth; - unsigned long int horizresolution, vertresolution; - char compressor_name[32]; - fileid->Seek(24, wxFromCurrent); - fileid->Read(&width, sizeof(unsigned short int)); - width = BYTE_SWAP2(width); - fileid->Read(&height, sizeof(unsigned short int)); - height = BYTE_SWAP2(height); - fileid->Read(&horizresolution, sizeof(unsigned long int)); - horizresolution = BYTE_SWAP4(horizresolution); - fileid->Read(&vertresolution, sizeof(unsigned long int)); - vertresolution = BYTE_SWAP4(vertresolution); - fileid->Seek(6, wxFromCurrent); - fileid->Read(compressor_name, sizeof(char) * 32); - fileid->Read(&depth, sizeof(unsigned short int)); - depth = BYTE_SWAP2(depth); - wxTreeItemId currid = m_tree->AppendItem(parentid, - wxString::Format(wxT("Dimensions: %d x %d @ %d bpp"), width, height, depth), - 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("Resolution: %d.%d x %d.%d"), horizresolution >> 16, horizresolution & 0x0000FFFF, - vertresolution >> 16, vertresolution & 0x0000FFFF), - m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1, - new OPJMarkerData(wxT("INFO")) - ); - currid = m_tree->AppendItem(parentid, - wxString::Format(wxT("Compressor: %.32s"), compressor_name), - m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1, - new OPJMarkerData(wxT("INFO")) - ); - jpeg2000parse(fileid, filepoint + 78, filelimit, parentid, level + 1, scansign, scanpoint); - - }; - break; - - /* Media Header box */ - case (MDHD_BOX): { - unsigned long int version; - unsigned short int language; - fileid->Read(&version, sizeof(unsigned long int)); - version = BYTE_SWAP4(version); - if (version == 0) { - unsigned long int creation_time, modification_time, timescale, duration; - fileid->Read(&creation_time, sizeof(unsigned long int)); - creation_time = BYTE_SWAP4(creation_time); - fileid->Read(&modification_time, sizeof(unsigned long int)); - modification_time = BYTE_SWAP4(modification_time); - fileid->Read(×cale, sizeof(unsigned long int)); - timescale = BYTE_SWAP4(timescale); - fileid->Read(&duration, sizeof(unsigned long int)); - duration = BYTE_SWAP4(duration); - const long unix_time = creation_time - 2082844800L; - wxTreeItemId currid = m_tree->AppendItem(parentid, - wxString::Format(wxT("Creation time: %u (%.24s)"), creation_time, ctime(&unix_time)), - m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1, - new OPJMarkerData(wxT("INFO")) - ); - const long unix_time1 = modification_time - 2082844800L; - currid = m_tree->AppendItem(parentid, - wxString::Format(wxT("Modification time: %u (%.24s)"), modification_time, ctime(&unix_time1)), - m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1, - new OPJMarkerData(wxT("INFO")) - ); - currid = m_tree->AppendItem(parentid, - wxString::Format(wxT("Timescale: %u (%.6fs)"), timescale, 1.0 / (float) timescale), - m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1, - new OPJMarkerData(wxT("INFO")) - ); - currid = m_tree->AppendItem(parentid, - wxString::Format(wxT("Duration: %u (%.3fs)"), duration, (float) duration / (float) timescale), - m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1, - new OPJMarkerData(wxT("INFO")) - ); - } else { - int8byte creation_time, modification_time, duration; - unsigned long int timescale; - fileid->Read(&creation_time, sizeof(int8byte)); - creation_time = BYTE_SWAP8(creation_time); - 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(int8byte)); - duration = BYTE_SWAP8(duration); - wxTreeItemId currid = m_tree->AppendItem(parentid, - wxString::Format(wxT("Creation time: %u"), creation_time), - m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1, - new OPJMarkerData(wxT("INFO")) - ); - currid = m_tree->AppendItem(parentid, - wxString::Format(wxT("Modification time: %u"), modification_time), - m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1, - new OPJMarkerData(wxT("INFO")) - ); - currid = m_tree->AppendItem(parentid, - wxString::Format(wxT("Timescale: %u"), timescale), - m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1, - new OPJMarkerData(wxT("INFO")) - ); - currid = m_tree->AppendItem(parentid, - wxString::Format(wxT("Duration: %u"), duration), - m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1, - new OPJMarkerData(wxT("INFO")) - ); - } - fileid->Read(&language, sizeof(unsigned short int)); - - wxTreeItemId currid = m_tree->AppendItem(parentid, - wxString::Format(wxT("Language: %d (%c%c%c)"), language & 0xEFFF, - 0x60 + (char) ((language >> 10) & 0x001F), 0x60 + (char) ((language >> 5) & 0x001F), 0x60 + (char) ((language >> 0) & 0x001F)), - m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1, - new OPJMarkerData(wxT("INFO")) - ); - }; - break; - - /* Media Handler box */ - case (HDLR_BOX): { - unsigned long int version, predefined, temp[3]; - char handler[4], name[256]; - int namelen = wxMin(256, (filelimit - filepoint - 24)); - fileid->Read(&version, sizeof(unsigned long int)); - version = BYTE_SWAP4(version); - fileid->Read(&predefined, sizeof(unsigned long int)); - fileid->Read(handler, 4 * sizeof(char)); - fileid->Read(&temp, 3 * sizeof(unsigned long int)); - fileid->Read(name, namelen * sizeof(char)); - - wxTreeItemId currid = m_tree->AppendItem(parentid, - wxString::Format(wxT("Handler: %.4s"), handler), - m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1, - new OPJMarkerData(wxT("INFO")) - ); - - currid = m_tree->AppendItem(parentid, - wxString::Format(wxT("Name: %.255s"), name), - m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1, - new OPJMarkerData(wxT("INFO")) - ); - - } - break; - - /* not yet implemented */ - default: - break; - - }; - - return (0); -} - - -void OPJParseThread::ParseJP2File(wxFile *fileid, wxFileOffset filepoint, wxFileOffset filelimit, wxTreeItemId parentid) -{ - unsigned long int scanpoint; - - jpeg2000parse(fileid, filepoint, filelimit, parentid, 0, NULL, &scanpoint); -} - -/* the parsing function itself */ -/* - fileid = fid of the file to scan (you should open it by yourself) - filepoint = first byte where to start to scan from (usually 0) - filelimit = first byte where to stop to scan from (usually the file size) - level = set this to 0 - scansign = signature to scan for (NULL avoids search, returns " " if successful) - scanpoint = point where the scan signature lies -*/ -int OPJParseThread::jpeg2000parse(wxFile *fileid, wxFileOffset filepoint, wxFileOffset filelimit, - wxTreeItemId parentid, int level, char *scansign, unsigned long int *scanpoint) -{ - unsigned long int LBox = 0x00000000; - //int LBox_read; - char TBox[5] = "\0\0\0\0"; - //int TBox_read; - int8byte XLBox = 0x0000000000000000; - //int XLBox_read; - unsigned long int box_length = 0; - int last_box = 0, box_num = 0; - int box_type = ANY_BOX; - unsigned char /*onebyte[1], twobytes[2],*/ fourbytes[4]; - - /* cycle all over the file */ - box_num = 0; - last_box = 0; - while (!last_box) { - - /* do not exceed file limit */ - if (filepoint >= filelimit) - return (0); - - /* seek on file */ - if (fileid->Seek(filepoint, wxFromStart) == wxInvalidOffset) - return (-1); - - /* read the mandatory LBox, 4 bytes */ - if (fileid->Read(fourbytes, 4) < 4) { - WriteText(wxT("Problem reading LBox from the file (file ended?)")); - return -1; - }; - LBox = STREAM_TO_UINT32(fourbytes, 0); - - /* read the mandatory TBox, 4 bytes */ - if (fileid->Read(TBox, 4) < 4) { - WriteText(wxT("Problem reading TBox from the file (file ended?)")); - return -1; - }; - - /* look if scansign is got */ - if ((scansign != NULL) && (memcmp(TBox, scansign, 4) == 0)) { - memcpy(scansign, " ", 4); - *scanpoint = filepoint; - - /* hack/exploit */ - // stop as soon as you find the codebox - return (0); - - }; - - /* determine the box type */ - for (box_type = JP_BOX; box_type < UNK_BOX; box_type++) - if (memcmp(TBox, j22box[box_type].value, 4) == 0) - break; - - /* read the optional XLBox, 8 bytes */ - if (LBox == 1) { - - if (fileid->Read(&XLBox, 8) < 8) { - WriteText(wxT("Problem reading XLBox from the file (file ended?)")); - return -1; - }; - box_length = (unsigned long int) BYTE_SWAP8(XLBox); - - } else if (LBox == 0x00000000) { - - /* last box in file */ - last_box = 1; - box_length = filelimit - filepoint; - - } else - - box_length = LBox; - - /* show box info */ - - // append the marker - int image, imageSel; - image = m_tree->TreeCtrlIcon_Folder; - imageSel = image + 1; - wxTreeItemId currid = m_tree->AppendItem(parentid, - wxString::Format(wxT("%03d: "), box_num) + - wxString::FromAscii(TBox) + - wxString::Format(wxT(" (0x%04X)"), - ((unsigned long int) TBox[3]) + ((unsigned long int) TBox[2] << 8) + - ((unsigned long int) TBox[1] << 16) + ((unsigned long int) TBox[0] << 24) - ), - image, imageSel, - new OPJMarkerData(wxT("BOX"), m_tree->m_fname.GetFullPath(), filepoint, filepoint + box_length) - ); - - // append some info - image = m_tree->TreeCtrlIcon_File; - imageSel = image + 1; - - // box name - wxTreeItemId subcurrid1 = m_tree->AppendItem(currid, - wxT("*** ") + wxString::FromAscii(j22box[box_type].name) + wxT(" ***"), - image, imageSel, - new OPJMarkerData(wxT("INFO")) - ); - m_tree->SetItemFont(subcurrid1, *wxITALIC_FONT); - - // position and length - wxTreeItemId subcurrid2 = m_tree->AppendItem(currid, - wxLongLong(filepoint).ToString() + wxT(" > ") + wxLongLong(filepoint + box_length - 1).ToString() + - wxT(", ") + wxString::Format(wxT("%d + 8 (%d)"), box_length, box_length + 8), - image, imageSel, - new OPJMarkerData(wxT("INFO")) - ); - - /* go deep in the box */ - box_handler_function((int) box_type, fileid, (LBox == 1) ? (filepoint + 16) : (filepoint + 8), filepoint + box_length, - currid, level, scansign, scanpoint); - - /* if it's a superbox go inside it */ - if (j22box[box_type].sbox) - jpeg2000parse(fileid, (LBox == 1) ? (filepoint + 16) : (filepoint + 8), filepoint + box_length, - currid, level + 1, scansign, scanpoint); - - /* increment box number and filepoint*/ - box_num++; - filepoint += box_length; - - }; - - /* all good */ - return (0); -} - +/* + * Copyright (c) 2007, Digital Signal Processing Laboratory, Università degli studi di Perugia (UPG), Italy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are 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. + */ +#include "OPJViewer.h" + +/* defines */ +#define SHORT_DESCR_LEN 32 +#define LONG_DESCR_LEN 256 + +/* enumeration for file formats */ +#define J2FILENUM 4 +typedef enum { + + JP2_FILE, + J2K_FILE, + MJ2_FILE, + UNK_FILE + +} j2filetype; + +/* enumeration for the box types */ +#define j22boxNUM 23 +typedef enum { + + FILE_BOX, + JP_BOX, + FTYP_BOX, + JP2H_BOX, + IHDR_BOX, + COLR_BOX, + JP2C_BOX, + JP2I_BOX, + XML_BOX, + UUID_BOX, + UINF_BOX, + MOOV_BOX, + MVHD_BOX, + TRAK_BOX, + TKHD_BOX, + MDIA_BOX, + MDHD_BOX, + HDLR_BOX, + MINF_BOX, + VMHD_BOX, + STBL_BOX, + STSD_BOX, + STSZ_BOX, + MJP2_BOX, + MDAT_BOX, + ANY_BOX, + UNK_BOX + +} j22boxtype; + +/* the box structure itself */ +struct boxdef { + + char value[5]; /* hexadecimal value/string*/ + char name[SHORT_DESCR_LEN]; /* short description */ + char descr[LONG_DESCR_LEN]; /* long description */ + int sbox; /* is it a superbox? */ + int req[J2FILENUM]; /* mandatory box */ + j22boxtype ins; /* contained in box... */ + +}; + + +/* jp2 family box signatures */ +#define FILE_SIGN "" +#define JP_SIGN "jP\040\040" +#define FTYP_SIGN "ftyp" +#define JP2H_SIGN "jp2h" +#define IHDR_SIGN "ihdr" +#define COLR_SIGN "colr" +#define JP2C_SIGN "jp2c" +#define JP2I_SIGN "jp2i" +#define XML_SIGN "xml\040" +#define UUID_SIGN "uuid" +#define UINF_SIGN "uinf" +#define MOOV_SIGN "moov" +#define MVHD_SIGN "mvhd" +#define TRAK_SIGN "trak" +#define TKHD_SIGN "tkhd" +#define MDIA_SIGN "mdia" +#define MDHD_SIGN "mdhd" +#define HDLR_SIGN "hdlr" +#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 "" +#define UNK_SIGN "" + +/* the possible boxes */ +struct boxdef j22box[] = +{ +/* sign */ {FILE_SIGN, +/* short */ "placeholder for nothing", +/* long */ "Nothing to say", +/* sbox */ 0, +/* req */ {1, 1, 1}, +/* ins */ FILE_BOX}, + +/* sign */ {JP_SIGN, +/* short */ "JPEG 2000 Signature box", +/* long */ "This box uniquely identifies the file as being part of the JPEG 2000 family of files", +/* sbox */ 0, +/* req */ {1, 1, 1}, +/* ins */ FILE_BOX}, + +/* sign */ {FTYP_SIGN, +/* short */ "File Type box", +/* long */ "This box specifies file type, version and compatibility information, including specifying if this file " + "is a conforming JP2 file or if it can be read by a conforming JP2 reader", +/* sbox */ 0, +/* req */ {1, 1, 1}, +/* ins */ FILE_BOX}, + +/* sign */ {JP2H_SIGN, +/* short */ "JP2 Header box", +/* long */ "This box contains a series of boxes that contain header-type information about the file", +/* sbox */ 1, +/* req */ {1, 1, 1}, +/* ins */ FILE_BOX}, + +/* sign */ {IHDR_SIGN, +/* short */ "Image Header box", +/* long */ "This box specifies the size of the image and other related fields", +/* sbox */ 0, +/* req */ {1, 1, 1}, +/* ins */ JP2H_BOX}, + +/* sign */ {COLR_SIGN, +/* short */ "Colour Specification box", +/* long */ "This box specifies the colourspace of the image", +/* sbox */ 0, +/* req */ {1, 1, 1}, +/* ins */ JP2H_BOX}, + +/* sign */ {JP2C_SIGN, +/* short */ "Contiguous Codestream box", +/* long */ "This box contains the codestream as defined by Annex A", +/* sbox */ 0, +/* req */ {1, 1, 1}, +/* ins */ FILE_BOX}, + +/* sign */ {JP2I_SIGN, +/* short */ "Intellectual Property box", +/* long */ "This box contains intellectual property information about the image", +/* sbox */ 0, +/* req */ {0, 0, 0}, +/* ins */ FILE_BOX}, + +/* sign */ {XML_SIGN, +/* short */ "XML box", +/* long */ "This box provides a tool by which vendors can add XML formatted information to a JP2 file", +/* sbox */ 0, +/* req */ {0, 0, 0}, +/* ins */ FILE_BOX}, + +/* sign */ {UUID_SIGN, +/* short */ "UUID box", +/* long */ "This box provides a tool by which vendors can add additional information to a file " + "without risking conflict with other vendors", +/* sbox */ 0, +/* req */ {0, 0, 0}, +/* ins */ FILE_BOX}, + +/* sign */ {UINF_SIGN, +/* short */ "UUID Info box", +/* long */ "This box provides a tool by which a vendor may provide access to additional information associated with a UUID", +/* sbox */ 0, +/* req */ {0, 0, 0}, +/* ins */ FILE_BOX}, + +/* sign */ {MOOV_SIGN, +/* short */ "Movie box", +/* long */ "This box contains the media data. In video tracks, this box would contain JPEG2000 video frames", +/* sbox */ 1, +/* req */ {1, 1, 1}, +/* ins */ FILE_BOX}, + +/* sign */ {MVHD_SIGN, +/* short */ "Movie Header box", +/* long */ "This box defines overall information which is media-independent, and relevant to the entire presentation " + "considered as a whole", +/* sbox */ 0, +/* req */ {1, 1, 1}, +/* ins */ MOOV_BOX}, + +/* sign */ {TRAK_SIGN, +/* short */ "Track box", +/* long */ "This is a container box for a single track of a presentation. A presentation may consist of one or more tracks", +/* sbox */ 1, +/* req */ {1, 1, 1}, +/* ins */ MOOV_BOX}, + +/* sign */ {TKHD_SIGN, +/* short */ "Track Header box", +/* long */ "This box specifies the characteristics of a single track. Exactly one Track Header Box is contained in a track", +/* sbox */ 0, +/* req */ {1, 1, 1}, +/* ins */ TRAK_BOX}, + +/* sign */ {MDIA_SIGN, +/* short */ "Media box", +/* long */ "The media declaration container contains all the objects which declare information about the media data " + "within a track", +/* sbox */ 1, +/* req */ {1, 1, 1}, +/* ins */ TRAK_BOX}, + +/* sign */ {MDHD_SIGN, +/* short */ "Media Header box", +/* long */ "The media header declares overall information which is media-independent, and relevant to characteristics " + "of the media in a track", +/* sbox */ 0, +/* req */ {1, 1, 1}, +/* ins */ MDIA_BOX}, + +/* sign */ {HDLR_SIGN, +/* short */ "Handler Reference box", +/* long */ "This box within a Media Box declares the process by which the media-data in the track may be presented, " + "and thus, the nature of the media in a track", +/* sbox */ 0, +/* req */ {1, 1, 1}, +/* ins */ MDIA_BOX}, + +/* sign */ {MINF_SIGN, +/* short */ "Media Information box", +/* long */ "This box contains all the objects which declare characteristic information of the media in the track", +/* sbox */ 1, +/* 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", +/* sbox */ 1, +/* req */ {1, 1, 1}, +/* ins */ MINF_BOX}, + +/* sign */ {STSD_SIGN, +/* 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 " + "information needed for that coding", +/* sbox */ 0, +/* req */ {1, 1, 1}, +/* ins */ MINF_BOX}, + +/* sign */ {MDAT_SIGN, +/* short */ "Media Data box", +/* long */ "The meta-data for a presentation is stored in the single Movie Box which occurs at the top-level of a file", +/* sbox */ 1, +/* req */ {1, 1, 1}, +/* ins */ FILE_BOX}, + +/* sign */ {ANY_SIGN, +/* short */ "Any box", +/* long */ "All the existing boxes", +/* sbox */ 0, +/* req */ {0, 0, 0}, +/* ins */ FILE_BOX}, + +/* sign */ {UNK_SIGN, +/* short */ "Unknown Type box", +/* long */ "The signature is not recognised to be that of an existing box", +/* sbox */ 0, +/* req */ {0, 0, 0}, +/* ins */ ANY_BOX} + +}; + + +/* macro functions */ +/* From little endian to big endian, 2 and 4 bytes */ +#define BYTE_SWAP2(X) ((X & 0x00FF) << 8) | ((X & 0xFF00) >> 8) +#define BYTE_SWAP4(X) ((X & 0x000000FF) << 24) | ((X & 0x0000FF00) << 8) | ((X & 0x00FF0000) >> 8) | ((X & 0xFF000000) >> 24) + +#ifdef __WXGTK__ +#define BYTE_SWAP8(X) ((X & 0x00000000000000FFULL) << 56) | ((X & 0x000000000000FF00ULL) << 40) | \ + ((X & 0x0000000000FF0000ULL) << 24) | ((X & 0x00000000FF000000ULL) << 8) | \ + ((X & 0x000000FF00000000ULL) >> 8) | ((X & 0x0000FF0000000000ULL) >> 24) | \ + ((X & 0x00FF000000000000ULL) >> 40) | ((X & 0xFF00000000000000ULL) >> 56) +#else +#define BYTE_SWAP8(X) ((X & 0x00000000000000FF) << 56) | ((X & 0x000000000000FF00) << 40) | \ + ((X & 0x0000000000FF0000) << 24) | ((X & 0x00000000FF000000) << 8) | \ + ((X & 0x000000FF00000000) >> 8) | ((X & 0x0000FF0000000000) >> 24) | \ + ((X & 0x00FF000000000000) >> 40) | ((X & 0xFF00000000000000) >> 56) +#endif + +/* From codestream to int values */ +#define STREAM_TO_UINT32(C, P) (((unsigned long int) (C)[(P) + 0] << 24) + \ + ((unsigned long int) (C)[(P) + 1] << 16) + \ + ((unsigned long int) (C)[(P) + 2] << 8) + \ + ((unsigned long int) (C)[(P) + 3] << 0)) + +#define STREAM_TO_UINT16(C, P) (((unsigned long int) (C)[(P) + 0] << 8) + \ + ((unsigned long int) (C)[(P) + 1] << 0)) + +#define OPJREAD_LONG(F,L,N) { \ + if (F->Read(fourbytes, 4) < 4) { \ + wxLogMessage(wxT("Problem reading " N " from the file (file ended?)")); \ + return -1; \ + }; \ + L = STREAM_TO_UINT32(fourbytes, 0); \ + } + +/* handling functions */ +#define ITEM_PER_ROW 10 + +//#define indprint if (0) printf("%.*s", 2 * level + 9, indent), printf +char indent[] = " " + " " + " " + " "; + +void indprint(wxString printout, int level) +{ + wxLogMessage(/*wxString::Format(wxT("%.*s"), 2 * level + 9, indent) + */printout); +} + +/* Box handler function */ +int OPJParseThread::box_handler_function(int boxtype, wxFile *fileid, wxFileOffset filepoint, wxFileOffset filelimit, + wxTreeItemId parentid, int level, char *scansign, unsigned long int *scanpoint) +{ + switch ((j22boxtype) boxtype) { + + + /* JPEG 2000 Signature box */ + case (JP_BOX): { + + unsigned long int checkdata = 0; + fileid->Read(&checkdata, sizeof(unsigned long int)); + checkdata = BYTE_SWAP4(checkdata); + + // add info + wxTreeItemId currid = m_tree->AppendItem(parentid, + wxString::Format(wxT("Check data: %X -> %s"), checkdata, (checkdata == 0x0D0A870A) ? wxT("OK") : wxT("KO")), + m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1, + new OPJMarkerData(wxT("INFO")) + ); + + }; + break; + + + /* JPEG 2000 codestream box */ + case (JP2C_BOX): { + + // add info + wxTreeItemId currid = m_tree->AppendItem(parentid, + wxString(wxT("Codestream")), + m_tree->TreeCtrlIcon_Folder, m_tree->TreeCtrlIcon_Folder + 1, + new OPJMarkerData(wxT("INFO-CSTREAM"), m_tree->m_fname.GetFullPath(), filepoint, filelimit) + ); + + m_tree->SetItemHasChildren(currid); + + // parse the file + //ParseJ2KFile(fileid, filepoint, filelimit, currid); + + }; + break; + + + + + + /* File Type box */ + case (FTYP_BOX): { + + char BR[4], CL[4]; + unsigned long int MinV, numCL, i; + fileid->Read(BR, sizeof(char) * 4); + fileid->Read(&MinV, sizeof(unsigned long int)); + MinV = BYTE_SWAP4(MinV); + numCL = (filelimit - fileid->Tell()) / 4; + + // add info + wxTreeItemId currid = m_tree->AppendItem(parentid, + wxT("Brand/Minor version: ") + + wxString::FromAscii(BR).Truncate(4) + + wxString::Format(wxT("/%d"), MinV), + m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1, + new OPJMarkerData(wxT("INFO")) + ); + + currid = m_tree->AppendItem(parentid, + wxString::Format(wxT("Compatibility list")), + m_tree->TreeCtrlIcon_Folder, m_tree->TreeCtrlIcon_Folder + 1, + new OPJMarkerData(wxT("INFO")) + ); + + for (i = 0; i < numCL; i++) { + fileid->Read(CL, sizeof(char) * 4); + m_tree->AppendItem(currid, + wxString::FromAscii(CL).Truncate(4), + m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1, + new OPJMarkerData(wxT("INFO")) + ); + }; + + }; + break; + + + + /* JP2 Header box */ + case (IHDR_BOX): { + + unsigned long int height, width; + unsigned short int nc; + unsigned char bpc, C, UnkC, IPR; + fileid->Read(&height, sizeof(unsigned long int)); + height = BYTE_SWAP4(height); + fileid->Read(&width, sizeof(unsigned long int)); + width = BYTE_SWAP4(width); + fileid->Read(&nc, sizeof(unsigned short int)); + nc = BYTE_SWAP2(nc); + fileid->Read(&bpc, sizeof(unsigned char)); + fileid->Read(&C, sizeof(unsigned char)); + fileid->Read(&UnkC, sizeof(unsigned char)); + fileid->Read(&IPR, sizeof(unsigned char)); + + // add info + wxTreeItemId currid = m_tree->AppendItem(parentid, + wxString::Format(wxT("Dimensions: %d x %d x %d @ %d bpc"), width, height, nc, bpc + 1), + m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1, + new OPJMarkerData(wxT("INFO")) + ); + + currid = m_tree->AppendItem(parentid, + wxString::Format(wxT("Compression type: %d"), C), + m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1, + new OPJMarkerData(wxT("INFO")) + ); + + currid = m_tree->AppendItem(parentid, + wxString::Format(wxT("Colourspace unknown: %d"), UnkC), + m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1, + new OPJMarkerData(wxT("INFO")) + ); + + currid = m_tree->AppendItem(parentid, + wxString::Format(wxT("Intellectual Property Rights: %d"), IPR), + m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1, + new OPJMarkerData(wxT("INFO")) + ); + + }; + break; + + + + /* Colour Specification box */ + case (COLR_BOX): { + + unsigned char METH, PREC, APPROX; + char methdescr[80], enumcsdescr[80]; + unsigned long int EnumCS; + fileid->Read(&METH, sizeof(unsigned char)); + switch (METH) { + case 1: + strcpy(methdescr, "Enumerated Colourspace"); + break; + case 2: + strcpy(methdescr, "Restricted ICC profile"); + break; + default: + strcpy(methdescr, "Unknown"); + break; + }; + fileid->Read(&PREC, sizeof(unsigned char)); + fileid->Read(&APPROX, sizeof(unsigned char)); + if (METH != 2) { + fileid->Read(&EnumCS, sizeof(unsigned long int)); + EnumCS = BYTE_SWAP4(EnumCS); + switch (EnumCS) { + case 16: + strcpy(enumcsdescr, "sRGB"); + break; + case 17: + strcpy(enumcsdescr, "greyscale"); + break; + case 18: + strcpy(enumcsdescr, "sYCC"); + break; + default: + strcpy(enumcsdescr, "Unknown"); + break; + }; + }; + + // add info + wxTreeItemId currid = m_tree->AppendItem(parentid, + wxString::Format(wxT("Specification method: %d ("), METH) + + wxString::FromAscii(methdescr) + + wxT(")"), + m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1, + new OPJMarkerData(wxT("INFO")) + ); + + currid = m_tree->AppendItem(parentid, + wxString::Format(wxT("Precedence: %d"), PREC), + m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1, + new OPJMarkerData(wxT("INFO")) + ); + + currid = m_tree->AppendItem(parentid, + wxString::Format(wxT("Colourspace approximation: %d"), APPROX), + m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1, + new OPJMarkerData(wxT("INFO")) + ); + + if (METH != 2) + currid = m_tree->AppendItem(parentid, + wxString::Format(wxT("Enumerated colourspace: %d ("), EnumCS) + + wxString::FromAscii(enumcsdescr) + + wxT(")"), + m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1, + new OPJMarkerData(wxT("INFO")) + ); + + if (METH != 1) + currid = m_tree->AppendItem(parentid, + wxString::Format(wxT("ICC profile: there is one")), + m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1, + new OPJMarkerData(wxT("INFO")) + ); + + + }; + break; + + + + + + + /* Movie Header Box */ + case (MVHD_BOX): { + + unsigned long int version, rate, matrix[9], next_track_ID; + unsigned short int volume; + fileid->Read(&version, sizeof(unsigned long int)); + version = BYTE_SWAP4(version); + if (version == 0) { + unsigned long int creation_time, modification_time, timescale, duration; + fileid->Read(&creation_time, sizeof(unsigned long int)); + creation_time = BYTE_SWAP4(creation_time); + fileid->Read(&modification_time, sizeof(unsigned long int)); + modification_time = BYTE_SWAP4(modification_time); + fileid->Read(×cale, sizeof(unsigned long int)); + timescale = BYTE_SWAP4(timescale); + fileid->Read(&duration, sizeof(unsigned long int)); + duration = BYTE_SWAP4(duration); + const long unix_time = creation_time - 2082844800L; + wxTreeItemId currid = m_tree->AppendItem(parentid, + wxString::Format(wxT("Creation time: %u (%.24s)"), creation_time, ctime(&unix_time)), + m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1, + new OPJMarkerData(wxT("INFO")) + ); + const long unix_time1 = modification_time - 2082844800L; + currid = m_tree->AppendItem(parentid, + wxString::Format(wxT("Modification time: %u (%.24s)"), modification_time, ctime(&unix_time1)), + m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1, + new OPJMarkerData(wxT("INFO")) + ); + currid = m_tree->AppendItem(parentid, + wxString::Format(wxT("Timescale: %u (%.6fs)"), timescale, 1.0 / (float) timescale), + m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1, + new OPJMarkerData(wxT("INFO")) + ); + currid = m_tree->AppendItem(parentid, + wxString::Format(wxT("Duration: %u (%.3fs)"), duration, (float) duration / (float) timescale), + m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1, + new OPJMarkerData(wxT("INFO")) + ); + } else { + int8byte creation_time, modification_time, duration; + unsigned long int timescale; + fileid->Read(&creation_time, sizeof(int8byte)); + creation_time = BYTE_SWAP8(creation_time); + 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(int8byte)); + duration = BYTE_SWAP8(duration); + wxTreeItemId currid = m_tree->AppendItem(parentid, + wxString::Format(wxT("Creation time: %u"), creation_time), + m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1, + new OPJMarkerData(wxT("INFO")) + ); + currid = m_tree->AppendItem(parentid, + wxString::Format(wxT("Modification time: %u"), modification_time), + m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1, + new OPJMarkerData(wxT("INFO")) + ); + currid = m_tree->AppendItem(parentid, + wxString::Format(wxT("Timescale: %u"), timescale), + m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1, + new OPJMarkerData(wxT("INFO")) + ); + currid = m_tree->AppendItem(parentid, + wxString::Format(wxT("Duration: %u"), duration), + m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1, + new OPJMarkerData(wxT("INFO")) + ); + }; + fileid->Read(&rate, sizeof(unsigned long int)); + rate = BYTE_SWAP4(rate); + fileid->Read(&volume, sizeof(unsigned short int)); + volume = BYTE_SWAP2(volume); + fileid->Seek(6, wxFromCurrent); + fileid->Read(&matrix, sizeof(unsigned char) * 9); + fileid->Seek(4, wxFromCurrent); + fileid->Read(&next_track_ID, sizeof(unsigned long int)); + next_track_ID = BYTE_SWAP4(next_track_ID); + wxTreeItemId currid = m_tree->AppendItem(parentid, + wxString::Format(wxT("Rate: %d (%d.%d)"), rate, rate >> 16, rate & 0x0000FFFF), + m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1, + new OPJMarkerData(wxT("INFO")) + ); + currid = m_tree->AppendItem(parentid, + wxString::Format(wxT("Volume: %d (%d.%d)"), volume, volume >> 8, volume & 0x00FF), + m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1, + new OPJMarkerData(wxT("INFO")) + ); + currid = m_tree->AppendItem(parentid, + wxString::Format(wxT("Next track ID: %d"), next_track_ID), + m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1, + new OPJMarkerData(wxT("INFO")) + ); + }; + break; + + + /* Sample Description box */ + case (STSD_BOX): { + + unsigned long int version, entry_count; + fileid->Read(&version, sizeof(unsigned long int)); + version = BYTE_SWAP4(version); + fileid->Read(&entry_count, sizeof(unsigned long int)); + entry_count = BYTE_SWAP4(entry_count); + wxTreeItemId currid = m_tree->AppendItem(parentid, + wxString::Format(wxT("Entry count: %d"), entry_count), + m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1, + new OPJMarkerData(wxT("INFO"), m_tree->m_fname.GetFullPath(), filepoint, filelimit) + ); + jpeg2000parse(fileid, filepoint + 8, filelimit, parentid, level + 1, scansign, scanpoint); + }; + 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 (unsigned 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 (")) + + wxString::FromAscii(graphicsdescr) + + wxT(")"), + 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): { + + unsigned short int height, width, depth; + unsigned long int horizresolution, vertresolution; + char compressor_name[32]; + fileid->Seek(24, wxFromCurrent); + fileid->Read(&width, sizeof(unsigned short int)); + width = BYTE_SWAP2(width); + fileid->Read(&height, sizeof(unsigned short int)); + height = BYTE_SWAP2(height); + fileid->Read(&horizresolution, sizeof(unsigned long int)); + horizresolution = BYTE_SWAP4(horizresolution); + fileid->Read(&vertresolution, sizeof(unsigned long int)); + vertresolution = BYTE_SWAP4(vertresolution); + fileid->Seek(6, wxFromCurrent); + fileid->Read(compressor_name, sizeof(char) * 32); + fileid->Read(&depth, sizeof(unsigned short int)); + depth = BYTE_SWAP2(depth); + wxTreeItemId currid = m_tree->AppendItem(parentid, + wxString::Format(wxT("Dimensions: %d x %d @ %d bpp"), width, height, depth), + 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("Resolution: %d.%d x %d.%d"), horizresolution >> 16, horizresolution & 0x0000FFFF, + vertresolution >> 16, vertresolution & 0x0000FFFF), + m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1, + new OPJMarkerData(wxT("INFO")) + ); + currid = m_tree->AppendItem(parentid, + wxString::Format(wxT("Compressor: %.32s"), compressor_name), + m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1, + new OPJMarkerData(wxT("INFO")) + ); + jpeg2000parse(fileid, filepoint + 78, filelimit, parentid, level + 1, scansign, scanpoint); + + }; + break; + + /* Media Header box */ + case (MDHD_BOX): { + unsigned long int version; + unsigned short int language; + fileid->Read(&version, sizeof(unsigned long int)); + version = BYTE_SWAP4(version); + if (version == 0) { + unsigned long int creation_time, modification_time, timescale, duration; + fileid->Read(&creation_time, sizeof(unsigned long int)); + creation_time = BYTE_SWAP4(creation_time); + fileid->Read(&modification_time, sizeof(unsigned long int)); + modification_time = BYTE_SWAP4(modification_time); + fileid->Read(×cale, sizeof(unsigned long int)); + timescale = BYTE_SWAP4(timescale); + fileid->Read(&duration, sizeof(unsigned long int)); + duration = BYTE_SWAP4(duration); + const long unix_time = creation_time - 2082844800L; + wxTreeItemId currid = m_tree->AppendItem(parentid, + wxString::Format(wxT("Creation time: %u (%.24s)"), creation_time, ctime(&unix_time)), + m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1, + new OPJMarkerData(wxT("INFO")) + ); + const long unix_time1 = modification_time - 2082844800L; + currid = m_tree->AppendItem(parentid, + wxString::Format(wxT("Modification time: %u (%.24s)"), modification_time, ctime(&unix_time1)), + m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1, + new OPJMarkerData(wxT("INFO")) + ); + currid = m_tree->AppendItem(parentid, + wxString::Format(wxT("Timescale: %u (%.6fs)"), timescale, 1.0 / (float) timescale), + m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1, + new OPJMarkerData(wxT("INFO")) + ); + currid = m_tree->AppendItem(parentid, + wxString::Format(wxT("Duration: %u (%.3fs)"), duration, (float) duration / (float) timescale), + m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1, + new OPJMarkerData(wxT("INFO")) + ); + } else { + int8byte creation_time, modification_time, duration; + unsigned long int timescale; + fileid->Read(&creation_time, sizeof(int8byte)); + creation_time = BYTE_SWAP8(creation_time); + 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(int8byte)); + duration = BYTE_SWAP8(duration); + wxTreeItemId currid = m_tree->AppendItem(parentid, + wxString::Format(wxT("Creation time: %u"), creation_time), + m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1, + new OPJMarkerData(wxT("INFO")) + ); + currid = m_tree->AppendItem(parentid, + wxString::Format(wxT("Modification time: %u"), modification_time), + m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1, + new OPJMarkerData(wxT("INFO")) + ); + currid = m_tree->AppendItem(parentid, + wxString::Format(wxT("Timescale: %u"), timescale), + m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1, + new OPJMarkerData(wxT("INFO")) + ); + currid = m_tree->AppendItem(parentid, + wxString::Format(wxT("Duration: %u"), duration), + m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1, + new OPJMarkerData(wxT("INFO")) + ); + } + fileid->Read(&language, sizeof(unsigned short int)); + + wxTreeItemId currid = m_tree->AppendItem(parentid, + wxString::Format(wxT("Language: %d (%c%c%c)"), language & 0xEFFF, + 0x60 + (char) ((language >> 10) & 0x001F), 0x60 + (char) ((language >> 5) & 0x001F), 0x60 + (char) ((language >> 0) & 0x001F)), + m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1, + new OPJMarkerData(wxT("INFO")) + ); + }; + break; + + /* Media Handler box */ + case (HDLR_BOX): { + unsigned long int version, predefined, temp[3]; + char handler[4], name[256]; + int namelen = wxMin(256, (filelimit - filepoint - 24)); + fileid->Read(&version, sizeof(unsigned long int)); + version = BYTE_SWAP4(version); + fileid->Read(&predefined, sizeof(unsigned long int)); + fileid->Read(handler, 4 * sizeof(char)); + fileid->Read(&temp, 3 * sizeof(unsigned long int)); + fileid->Read(name, namelen * sizeof(char)); + + wxTreeItemId currid = m_tree->AppendItem(parentid, + wxString::Format(wxT("Handler: %.4s"), handler), + m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1, + new OPJMarkerData(wxT("INFO")) + ); + + currid = m_tree->AppendItem(parentid, + wxString::Format(wxT("Name: %.255s"), name), + m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1, + new OPJMarkerData(wxT("INFO")) + ); + + } + break; + + /* not yet implemented */ + default: + break; + + }; + + return (0); +} + + +void OPJParseThread::ParseJP2File(wxFile *fileid, wxFileOffset filepoint, wxFileOffset filelimit, wxTreeItemId parentid) +{ + unsigned long int scanpoint; + + jpeg2000parse(fileid, filepoint, filelimit, parentid, 0, NULL, &scanpoint); +} + +/* the parsing function itself */ +/* + fileid = fid of the file to scan (you should open it by yourself) + filepoint = first byte where to start to scan from (usually 0) + filelimit = first byte where to stop to scan from (usually the file size) + level = set this to 0 + scansign = signature to scan for (NULL avoids search, returns " " if successful) + scanpoint = point where the scan signature lies +*/ +int OPJParseThread::jpeg2000parse(wxFile *fileid, wxFileOffset filepoint, wxFileOffset filelimit, + wxTreeItemId parentid, int level, char *scansign, unsigned long int *scanpoint) +{ + unsigned long int LBox = 0x00000000; + //int LBox_read; + char TBox[5] = "\0\0\0\0"; + //int TBox_read; + int8byte XLBox = 0x0000000000000000; + //int XLBox_read; + unsigned long int box_length = 0; + int last_box = 0, box_num = 0; + int box_type = ANY_BOX; + unsigned char /*onebyte[1], twobytes[2],*/ fourbytes[4]; + + /* cycle all over the file */ + box_num = 0; + last_box = 0; + while (!last_box) { + + /* do not exceed file limit */ + if (filepoint >= filelimit) + return (0); + + /* seek on file */ + if (fileid->Seek(filepoint, wxFromStart) == wxInvalidOffset) + return (-1); + + /* read the mandatory LBox, 4 bytes */ + if (fileid->Read(fourbytes, 4) < 4) { + WriteText(wxT("Problem reading LBox from the file (file ended?)")); + return -1; + }; + LBox = STREAM_TO_UINT32(fourbytes, 0); + + /* read the mandatory TBox, 4 bytes */ + if (fileid->Read(TBox, 4) < 4) { + WriteText(wxT("Problem reading TBox from the file (file ended?)")); + return -1; + }; + + /* look if scansign is got */ + if ((scansign != NULL) && (memcmp(TBox, scansign, 4) == 0)) { + memcpy(scansign, " ", 4); + *scanpoint = filepoint; + + /* hack/exploit */ + // stop as soon as you find the codebox + return (0); + + }; + + /* determine the box type */ + for (box_type = JP_BOX; box_type < UNK_BOX; box_type++) + if (memcmp(TBox, j22box[box_type].value, 4) == 0) + break; + + /* read the optional XLBox, 8 bytes */ + if (LBox == 1) { + + if (fileid->Read(&XLBox, 8) < 8) { + WriteText(wxT("Problem reading XLBox from the file (file ended?)")); + return -1; + }; + box_length = (unsigned long int) BYTE_SWAP8(XLBox); + + } else if (LBox == 0x00000000) { + + /* last box in file */ + last_box = 1; + box_length = filelimit - filepoint; + + } else + + box_length = LBox; + + /* show box info */ + + // append the marker + int image, imageSel; + image = m_tree->TreeCtrlIcon_Folder; + imageSel = image + 1; + wxTreeItemId currid = m_tree->AppendItem(parentid, + wxString::Format(wxT("%03d: "), box_num) + + wxString::FromAscii(TBox) + + wxString::Format(wxT(" (0x%04X)"), + ((unsigned long int) TBox[3]) + ((unsigned long int) TBox[2] << 8) + + ((unsigned long int) TBox[1] << 16) + ((unsigned long int) TBox[0] << 24) + ), + image, imageSel, + new OPJMarkerData(wxT("BOX"), m_tree->m_fname.GetFullPath(), filepoint, filepoint + box_length) + ); + + // append some info + image = m_tree->TreeCtrlIcon_File; + imageSel = image + 1; + + // box name + wxTreeItemId subcurrid1 = m_tree->AppendItem(currid, + wxT("*** ") + wxString::FromAscii(j22box[box_type].name) + wxT(" ***"), + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + m_tree->SetItemFont(subcurrid1, *wxITALIC_FONT); + + // position and length + wxTreeItemId subcurrid2 = m_tree->AppendItem(currid, + wxLongLong(filepoint).ToString() + wxT(" > ") + wxLongLong(filepoint + box_length - 1).ToString() + + wxT(", ") + wxString::Format(wxT("%d + 8 (%d)"), box_length, box_length + 8), + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + /* go deep in the box */ + box_handler_function((int) box_type, fileid, (LBox == 1) ? (filepoint + 16) : (filepoint + 8), filepoint + box_length, + currid, level, scansign, scanpoint); + + /* if it's a superbox go inside it */ + if (j22box[box_type].sbox) + jpeg2000parse(fileid, (LBox == 1) ? (filepoint + 16) : (filepoint + 8), filepoint + box_length, + currid, level + 1, scansign, scanpoint); + + /* increment box number and filepoint*/ + box_num++; + filepoint += box_length; + + }; + + /* all good */ + return (0); +} +