From 3f36196dfdd740417d5dfd7d7d313dd179d4a304 Mon Sep 17 00:00:00 2001 From: Giuseppe Baruffa Date: Tue, 27 Mar 2007 12:48:17 +0000 Subject: Improved parsing in OPJViewer, as well some aesthetic modifications; support for image rendering with bit depths lower than 8 bits; can display an arbitrary frame of an MJ2 file (only in B/W, though); can reload a file; better image resizing capabilities --- OPJViewer/source/OPJViewer.cpp | 266 +++++-- OPJViewer/source/OPJViewer.h | 48 +- OPJViewer/source/about_htm.h | 48 ++ OPJViewer/source/imagj2k.cpp | 26 +- OPJViewer/source/imagmj2.cpp | 14 +- OPJViewer/source/imagmj2.h | 2 +- OPJViewer/source/opj_logo.xpm | 285 ++++++++ OPJViewer/source/wxj2kparser.cpp | 1420 +++++++++++++++++++++++++++++++++----- OPJViewer/source/wxjp2parser.cpp | 10 +- 9 files changed, 1873 insertions(+), 246 deletions(-) create mode 100644 OPJViewer/source/about_htm.h create mode 100644 OPJViewer/source/opj_logo.xpm (limited to 'OPJViewer/source') diff --git a/OPJViewer/source/OPJViewer.cpp b/OPJViewer/source/OPJViewer.cpp index b06ba2d9..ea075dcc 100644 --- a/OPJViewer/source/OPJViewer.cpp +++ b/OPJViewer/source/OPJViewer.cpp @@ -193,13 +193,18 @@ bool OPJViewerApp::OnInit(void) wxImage::AddHandler( new wxJP2Handler ); wxImage::AddHandler( new wxMJ2Handler ); #endif - // we use a PNG image in our HTML page - wxImage::AddHandler(new wxPNGHandler); + // we use a XPM image in our HTML page + wxImage::AddHandler(new wxXPMHandler); + + // memory file system + wxFileSystem::AddHandler(new wxMemoryFSHandler); // set decoding engine parameters + 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; @@ -225,7 +230,7 @@ bool OPJViewerApp::OnInit(void) if (!(m_filelist.IsEmpty())) { //wxLogMessage(wxT("Habemus files!!!")); wxArrayString paths, filenames; - for (int f = 0; f < wxGetApp().m_filelist.GetCount(); f++) { + 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()); } @@ -258,7 +263,9 @@ BEGIN_EVENT_TABLE(OPJFrame, wxMDIParentFrame) EVT_MENU(OPJFRAME_FILECLOSE, OPJFrame::OnClose) EVT_MENU(OPJFRAME_VIEWZOOM, OPJFrame::OnZoom) EVT_MENU(OPJFRAME_VIEWFIT, OPJFrame::OnFit) - EVT_MENU(OPJFRAME_FILETOGGLE, OPJFrame::OnToggleWindow) + EVT_MENU(OPJFRAME_VIEWRELOAD, OPJFrame::OnReload) + EVT_MENU(OPJFRAME_FILETOGGLEB, OPJFrame::OnToggleBrowser) + EVT_MENU(OPJFRAME_FILETOGGLEP, OPJFrame::OnTogglePeeker) 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) @@ -275,8 +282,11 @@ OPJFrame::OPJFrame(wxWindow *parent, const wxWindowID id, const wxString& title, file_menu->Append(OPJFRAME_FILEOPEN, wxT("&Open\tCtrl+O")); file_menu->SetHelpString(OPJFRAME_FILEOPEN, wxT("Open one or more files")); - file_menu->Append(OPJFRAME_FILETOGGLE, wxT("&Toggle browser\tCtrl+T")); - file_menu->SetHelpString(OPJFRAME_FILETOGGLE, wxT("Toggle the left browsing pane")); + 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_FILECLOSE, wxT("&Close\tCtrl+C")); file_menu->SetHelpString(OPJFRAME_FILECLOSE, wxT("Close current image")); @@ -293,6 +303,9 @@ OPJFrame::OPJFrame(wxWindow *parent, const wxWindowID id, const wxString& title, 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")); + // settings menu and its items wxMenu *sets_menu = new wxMenu; @@ -435,9 +448,11 @@ void OPJFrame::OnSetsDeco(wxCommandEvent& event) if (dialog.ShowModal() == wxID_OK) { // load settings + wxGetApp().m_resizemethod = dialog.m_resizeBox->GetSelection(); 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(); @@ -512,7 +527,7 @@ void OPJFrame::Rescale(int zooml, OPJChildFrame *currframe) if (zooml != 100) new_image.Rescale((int) ((double) zooml * (double) new_image.GetWidth() / 100.0), (int) ((double) zooml * (double) new_image.GetHeight() / 100.0), - wxIMAGE_QUALITY_NORMAL); + wxGetApp().m_resizemethod ? wxIMAGE_QUALITY_HIGH : wxIMAGE_QUALITY_NORMAL); currframe->m_canvas->m_image = wxBitmap(new_image); currframe->m_canvas->SetScrollbars(20, 20, @@ -526,21 +541,44 @@ void OPJFrame::Rescale(int zooml, OPJChildFrame *currframe) } +void OPJFrame::OnReload(wxCommandEvent& event) +{ + OPJChildFrame *currframe = (OPJChildFrame *) GetActiveChild(); + + 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; +} + + // 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("opj_logo.xpm", wxBitmap(opj_logo), wxBITMAP_TYPE_XPM); + topsizer = new wxBoxSizer(wxVERTICAL); - html = new wxHtmlWindow(&dlg, wxID_ANY, wxDefaultPosition, wxSize(350, 250), wxHW_SCROLLBAR_NEVER); + html = new wxHtmlWindow(&dlg, wxID_ANY, wxDefaultPosition, wxSize(320, 250), wxHW_SCROLLBAR_NEVER); html->SetBorders(0); - html->LoadPage(wxT("about/about.htm")); + //html->LoadPage(wxT("about/about.htm")); //html->SetPage("Hello, world!"); + html->SetPage(htmlaboutpage); html->SetSize(html->GetInternalRepresentation()->GetWidth(), html->GetInternalRepresentation()->GetHeight()); @@ -578,7 +616,7 @@ void OPJFrame::OnAbout(wxCommandEvent& WXUNUSED(event)) } -void OPJFrame::OnToggleWindow(wxCommandEvent& WXUNUSED(event)) +void OPJFrame::OnToggleBrowser(wxCommandEvent& WXUNUSED(event)) { if (markerTreeWindow->IsShown()) markerTreeWindow->Show(false); @@ -589,6 +627,17 @@ void OPJFrame::OnToggleWindow(wxCommandEvent& WXUNUSED(event)) layout.LayoutMDIFrame(this); } +void OPJFrame::OnTogglePeeker(wxCommandEvent& WXUNUSED(event)) +{ + if (loggingWindow->IsShown()) + loggingWindow->Show(false); + else + loggingWindow->Show(true); + + wxLayoutAlgorithm layout; + layout.LayoutMDIFrame(this); +} + void OPJFrame::OnSashDrag(wxSashEvent& event) { if (event.GetDragStatus() == wxSASH_STATUS_OUT_OF_RANGE) @@ -640,14 +689,14 @@ void OPJFrame::OpenFiles(wxArrayString paths, wxArrayString filenames) m_childhash[winNumber] = subframe; // create own marker tree - m_treehash[winNumber] = new OPJMarkerTree(m_bookCtrl, paths[n], wxT("Parsing..."), TreeTest_Ctrl, + 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 (int p = 0; p < m_bookCtrl->GetPageCount(); p++) { + 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; @@ -719,11 +768,22 @@ OPJDecoThread *OPJCanvas::CreateDecoThread(void) return dthread; } +#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); @@ -769,34 +829,33 @@ OPJChildFrame::OPJChildFrame(OPJFrame *parent, wxFileName fname, int winnumber, 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; + 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"))); + SetIcon(wxIcon(wxT("OPJChild16"))); #endif - // Give it a status line - /*CreateStatusBar();*/ + // Give it a status line + /*CreateStatusBar();*/ - int width, height; - GetClientSize(&width, &height); + int width, height; + GetClientSize(&width, &height); - OPJCanvas *canvas = new OPJCanvas(fname, this, wxPoint(0, 0), wxSize(width, height)); - canvas->SetCursor(wxCursor(wxCURSOR_PENCIL)); - m_canvas = canvas; + OPJCanvas *canvas = new OPJCanvas(fname, this, wxPoint(0, 0), wxSize(width, height)); + canvas->SetCursor(wxCursor(wxCURSOR_PENCIL)); + m_canvas = canvas; - // Give it scrollbars - canvas->SetScrollbars(20, 20, 5, 5); + // Give it scrollbars + canvas->SetScrollbars(20, 20, 5, 5); - Show(true); - Maximize(true); + Show(true); + Maximize(true); /*wxLogError(wxString::Format(wxT("Created tree %d (0x%x)"), m_winnumber, m_frame->m_treehash[m_winnumber]));*/ @@ -810,18 +869,15 @@ OPJChildFrame::~OPJChildFrame(void) void OPJChildFrame::OnClose(wxCloseEvent& event) { - for (int p = 0; p < m_frame->m_bookCtrl->GetPageCount(); p++) { - + 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) @@ -836,7 +892,7 @@ void OPJChildFrame::OnGotFocus(wxFocusEvent& event) if (!m_frame->m_bookCtrl) return; - for (int p = 0; p < m_frame->m_bookCtrl->GetPageCount(); p++) { + 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); @@ -898,7 +954,7 @@ IMPLEMENT_DYNAMIC_CLASS(OPJMarkerTree, wxGenericTreeCtrl) IMPLEMENT_DYNAMIC_CLASS(OPJMarkerTree, wxTreeCtrl) #endif -OPJMarkerTree::OPJMarkerTree(wxWindow *parent, wxFileName fname, wxString name, const wxWindowID id, +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) { @@ -915,11 +971,13 @@ OPJMarkerTree::OPJMarkerTree(wxWindow *parent, wxFileName fname, wxString name, image, image, new OPJMarkerData(name)); - OPJParseThread *pthread = CreateParseThread(); + 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) @@ -1048,15 +1106,16 @@ void OPJParseThread::LoadFile(wxFileName fname) } - // close the file - m_file.Close(); - // 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!")); } @@ -1199,7 +1258,7 @@ void OPJMarkerTree::LogEvent(const wxChar *name, const wxTreeEvent& event) wxLogMessage(wxT("%s(%s)"), name, text.c_str()); } -OPJParseThread *OPJMarkerTree::CreateParseThread(wxTreeItemId parentid) +OPJParseThread *OPJMarkerTree::CreateParseThread(wxTreeItemId parentid, OPJChildFrame *subframe) { OPJParseThread *pthread = new OPJParseThread(this, parentid); @@ -1804,6 +1863,7 @@ void *OPJDecoThread::Entry() mj222handler->m_reducefactor = wxGetApp().m_reducefactor; mj222handler->m_qualitylayers = wxGetApp().m_qualitylayers; mj222handler->m_components = wxGetApp().m_components; + mj222handler->m_framenum = wxGetApp().m_framenum; #ifdef USE_JPWL mj222handler->m_enablejpwl = wxGetApp().m_enablejpwl; mj222handler->m_expcomps = wxGetApp().m_expcomps; @@ -1943,40 +2003,36 @@ END_EVENT_TABLE() OPJDecoderDialog::OPJDecoderDialog(wxWindow* win, int dialogType) { - SetExtraStyle(wxDIALOG_EX_CONTEXTHELP|wxWS_EX_VALIDATE_RECURSIVELY); - - int tabImage1 = -1; - int tabImage2 = -1; - - int resizeBorder = wxRESIZE_BORDER; + SetExtraStyle(wxDIALOG_EX_CONTEXTHELP|wxWS_EX_VALIDATE_RECURSIVELY); - m_imageList = NULL; + Create(win, wxID_ANY, wxT("Decoder settings"), + wxDefaultPosition, wxDefaultSize, + wxDEFAULT_DIALOG_STYLE| (int) wxPlatform::IfNot(wxOS_WINDOWS_CE, wxRESIZE_BORDER) + ); - Create(win, wxID_ANY, wxT("Decoder settings"), wxDefaultPosition, wxDefaultSize, - wxDEFAULT_DIALOG_STYLE| (int) wxPlatform::IfNot(wxOS_WINDOWS_CE, resizeBorder) - ); + CreateButtons(wxOK | wxCANCEL | (int)wxPlatform::IfNot(wxOS_WINDOWS_CE, wxHELP)); - CreateButtons(wxOK | wxCANCEL | (int)wxPlatform::IfNot(wxOS_WINDOWS_CE, wxHELP)); + wxBookCtrlBase* notebook = GetBookCtrl(); - wxBookCtrlBase* notebook = GetBookCtrl(); - notebook->SetImageList(m_imageList); - - wxPanel* mainSettings = CreateMainSettingsPage(notebook); + wxPanel* mainSettings = CreateMainSettingsPage(notebook); + wxPanel* jpeg2000Settings = CreatePart1SettingsPage(notebook); + wxPanel* mjpeg2000Settings = CreatePart3SettingsPage(notebook); #ifdef USE_JPWL - wxPanel* jpwlSettings = CreateJPWLSettingsPage(notebook); + wxPanel* jpwlSettings = CreatePart11SettingsPage(notebook); #endif // USE_JPWL - notebook->AddPage(mainSettings, wxT("Main"), false); + notebook->AddPage(mainSettings, wxT("Display"), false); + notebook->AddPage(jpeg2000Settings, wxT("JPEG 2000"), false); + notebook->AddPage(mjpeg2000Settings, wxT("MJPEG 2000"), false); #ifdef USE_JPWL - notebook->AddPage(jpwlSettings, wxT("JPWL"), false); + notebook->AddPage(jpwlSettings, wxT("JPWL"), false); #endif // USE_JPWL - LayoutDialog(); + LayoutDialog(); } OPJDecoderDialog::~OPJDecoderDialog() { - delete m_imageList; } /*wxPanel* OPJDecoderDialog::CreateGeneralSettingsPage(wxWindow* parent) @@ -2084,6 +2140,87 @@ 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); + + // resize settings, column + wxString choices[] = {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); + + 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); @@ -2172,6 +2309,7 @@ wxPanel* OPJDecoderDialog::CreateMainSettingsPage(wxWindow* parent) wxSP_ARROW_KEYS, 0, 100000, wxGetApp().m_components), 0, wxALL | wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL, 5); + m_numcompsCtrl->Enable(false); compoSizer->Add(numcompsSizer, 0, wxGROW | wxALL, 5); @@ -2187,7 +2325,7 @@ wxPanel* OPJDecoderDialog::CreateMainSettingsPage(wxWindow* parent) } #ifdef USE_JPWL -wxPanel* OPJDecoderDialog::CreateJPWLSettingsPage(wxWindow* parent) +wxPanel* OPJDecoderDialog::CreatePart11SettingsPage(wxWindow* parent) { wxPanel* panel = new wxPanel(parent, wxID_ANY); @@ -2285,6 +2423,8 @@ void OPJDecoderDialog::OnEnableJPWL(wxCommandEvent& event) } +#endif // USE_JPWL + bool OPJDnDFile::OnDropFiles(wxCoord, wxCoord, const wxArrayString& filenames) { /*size_t nFiles = filenames.GetCount(); @@ -2299,5 +2439,3 @@ bool OPJDnDFile::OnDropFiles(wxCoord, wxCoord, const wxArrayString& filenames) return true; } -#endif // USE_JPWL - diff --git a/OPJViewer/source/OPJViewer.h b/OPJViewer/source/OPJViewer.h index 7a7ea328..ac64e393 100644 --- a/OPJViewer/source/OPJViewer.h +++ b/OPJViewer/source/OPJViewer.h @@ -94,6 +94,8 @@ #include #include "wx/wxhtml.h" #include "wx/statline.h" +#include + #include "libopenjpeg\openjpeg.h" @@ -119,11 +121,20 @@ typedef unsigned long long int8byte; #endif #endif +#define OPJ_APPLICATION wxT("OPJViewer") #define OPJ_APPLICATION_NAME wxT("OpenJPEG Viewer") #define OPJ_APPLICATION_VERSION wxT("0.2 alpha") #define OPJ_APPLICATION_TITLEBAR OPJ_APPLICATION_NAME wxT(" ") OPJ_APPLICATION_VERSION #define OPJ_APPLICATION_COPYRIGHT wxT("(C) 2007, Giuseppe Baruffa") +#ifdef __WXMSW__ +#define OPJ_APPLICATION_PLATFORM wxT("Windows") +#endif + +#ifdef __WXGTK__ +#define OPJ_APPLICATION_PLATFORM wxT("Linux") +#endif + #define OPJ_CANVAS_BORDER 10 #define OPJ_CANVAS_COLOUR *wxWHITE @@ -166,8 +177,11 @@ class OPJViewerApp: public wxApp // the list of all filenames written in the command line wxArrayString m_filelist; + // displaying engine parameters + int m_resizemethod; + // decoding engine parameters - int m_reducefactor, m_qualitylayers, m_components; + int m_reducefactor, m_qualitylayers, m_components, m_framenum; #ifdef USE_JPWL bool m_enablejpwl; int m_expcomps, m_maxtiles; @@ -241,15 +255,16 @@ public: }; OPJMarkerTree() { }; - OPJMarkerTree(wxWindow *parent, wxFileName fname, wxString name, const wxWindowID id, + 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); + 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); @@ -335,14 +350,16 @@ class OPJFrame: public wxMDIParentFrame OPJFrame(wxWindow *parent, const wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, const long style); ~OPJFrame(void); - void OnSize(wxSizeEvent& event); + void OnSize(wxSizeEvent& WXUNUSED(event)); void OnAbout(wxCommandEvent& WXUNUSED(event)); void OnFileOpen(wxCommandEvent& WXUNUSED(event)); void OnQuit(wxCommandEvent& WXUNUSED(event)); void OnClose(wxCommandEvent& WXUNUSED(event)); void OnZoom(wxCommandEvent& WXUNUSED(event)); void OnFit(wxCommandEvent& WXUNUSED(event)); - void OnToggleWindow(wxCommandEvent& WXUNUSED(event)); + void OnToggleBrowser(wxCommandEvent& WXUNUSED(event)); + void OnTogglePeeker(wxCommandEvent& WXUNUSED(event)); + void OnReload(wxCommandEvent& event); void OnSetsDeco(wxCommandEvent& event); void OnSashDrag(wxSashEvent& event); void OpenFiles(wxArrayString paths, wxArrayString filenames); @@ -390,6 +407,8 @@ class OPJChildFrame: public wxMDIChildFrame wxFileName m_fname; int m_winnumber; + unsigned long m_twidth, m_theight, m_tx, m_ty; + DECLARE_EVENT_TABLE() }; @@ -398,9 +417,11 @@ enum { OPJFRAME_FILEEXIT = wxID_EXIT, OPJFRAME_HELPABOUT = wxID_ABOUT, OPJFRAME_FILEOPEN, - OPJFRAME_FILETOGGLE, + OPJFRAME_FILETOGGLEB, + OPJFRAME_FILETOGGLEP, OPJFRAME_VIEWZOOM, OPJFRAME_VIEWFIT, + OPJFRAME_VIEWRELOAD, OPJFRAME_FILECLOSE, OPJFRAME_SETSDECO, @@ -533,12 +554,15 @@ public: ~OPJDecoderDialog(); wxSpinCtrl *m_reduceCtrl, *m_layerCtrl, *m_numcompsCtrl; + wxRadioBox* m_resizeBox; wxPanel* CreateMainSettingsPage(wxWindow* parent); + wxPanel* CreatePart1SettingsPage(wxWindow* parent); + wxPanel* CreatePart3SettingsPage(wxWindow* parent); #ifdef USE_JPWL void OnEnableJPWL(wxCommandEvent& event); - wxPanel* CreateJPWLSettingsPage(wxWindow* parent); - wxSpinCtrl *m_expcompsCtrl, *m_maxtilesCtrl; + wxPanel* CreatePart11SettingsPage(wxWindow* parent); + wxSpinCtrl *m_expcompsCtrl, *m_framenumCtrl, *m_maxtilesCtrl; wxCheckBox *m_enablejpwlCheck; #endif // USE_JPWL @@ -546,16 +570,16 @@ public: protected: enum { - OPJDECO_REDUCEFACTOR = 100, + OPJDECO_RESMETHOD = 100, + OPJDECO_REDUCEFACTOR, OPJDECO_QUALITYLAYERS, OPJDECO_NUMCOMPS, OPJDECO_ENABLEJPWL, OPJDECO_EXPCOMPS, - OPJDECO_MAXTILES + OPJDECO_MAXTILES, + OPJDECO_FRAMENUM }; - wxImageList* m_imageList; - DECLARE_EVENT_TABLE() }; diff --git a/OPJViewer/source/about_htm.h b/OPJViewer/source/about_htm.h new file mode 100644 index 00000000..bb295f72 --- /dev/null +++ b/OPJViewer/source/about_htm.h @@ -0,0 +1,48 @@ +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: " wxVERSION_STRING ", " __DATE__ ", " __TIME__ "
" +) +#ifdef USE_JPWL +wxT("- Compiled with JPWL support
") +#endif // USE_JPWL +#ifdef USE_JPSEC +wxT("- Compiled with JPSEC support") +#endif // USE_JPSEC +wxT( +"
" +"OpenJPEG is © 2002-2007 TELE - Université Catholique de Louvain
" +"OPJViewer is also © 2007 DSPLab - Università degli studi di Perugia" +"
" +"" +"" +); \ No newline at end of file diff --git a/OPJViewer/source/imagj2k.cpp b/OPJViewer/source/imagj2k.cpp index 2442aa4e..9f972095 100644 --- a/OPJViewer/source/imagj2k.cpp +++ b/OPJViewer/source/imagj2k.cpp @@ -233,14 +233,26 @@ bool wxJ2KHandler::LoadFile(wxImage *image, wxInputStream& stream, bool verbose, } } - } else { + + } 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++); - + } } } @@ -258,6 +270,16 @@ bool wxJ2KHandler::LoadFile(wxImage *image, wxInputStream& stream, bool verbose, *(ptr++) = (*(y)) >> shiftbpp; *(ptr++) = (*(y++)) >> shiftbpp; + } + } + } else if (shiftbpp < 0) { + for (row = 0; row < opjimage->comps[0].h; row++) { + for (col = 0; col < opjimage->comps[0].w; col++) { + + *(ptr++) = (*(y)) << -shiftbpp; + *(ptr++) = (*(y)) << -shiftbpp; + *(ptr++) = (*(y++)) << -shiftbpp; + } } } else { diff --git a/OPJViewer/source/imagmj2.cpp b/OPJViewer/source/imagmj2.cpp index 2a4d2e58..1a8e1ffb 100644 --- a/OPJViewer/source/imagmj2.cpp +++ b/OPJViewer/source/imagmj2.cpp @@ -402,15 +402,15 @@ my_jpeg2000parse(wxInputStream& stream, unsigned long int filepoint, unsigned lo char *scansign, unsigned long int *scanpoint) { unsigned long int LBox = 0x00000000; - int LBox_read; + //int LBox_read; char TBox[5] = "\0\0\0\0"; - int TBox_read; + //int TBox_read; __int64 XLBox = 0x0000000000000000; - int XLBox_read; + //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]; + unsigned char /*onebyte[1], twobytes[2],*/ fourbytes[4]; int box_number = 0; /* cycle all over the file */ @@ -499,7 +499,7 @@ my_jpeg2000parse(wxInputStream& stream, unsigned long int filepoint, unsigned lo // search first contiguos codestream box in an mj2 file unsigned long int -searchfirstjp2c(wxInputStream& stream, unsigned long int fsize) +searchjp2c(wxInputStream& stream, unsigned long int fsize, int number) { char scansign[] = "jp2c"; unsigned long int scanpoint = 0L; @@ -507,7 +507,7 @@ searchfirstjp2c(wxInputStream& stream, unsigned long int fsize) wxLogMessage(wxT("MJ2: searching jp2c box... ")); /* do the parsing */ - if (my_jpeg2000parse(stream, 0, fsize, 0, scansign, &scanpoint) < 0) + if (my_jpeg2000parse(stream, 0, fsize, number, scansign, &scanpoint) < 0) wxLogMessage(wxT("MJ2: Unrecoverable error during file parsing: stopping")); if (strcmp(scansign, " ")) @@ -638,7 +638,7 @@ bool wxMJ2Handler::LoadFile(wxImage *image, wxInputStream& stream, bool verbose, file_length = (int) stream.TellI(); /* search for the first codestream box and the movie header box */ - jp2c_point = searchfirstjp2c(stream, file_length); + jp2c_point = searchjp2c(stream, file_length, m_framenum); jp2h_point = searchjpegheaderbox(stream, file_length); // read the jp2h box and store it diff --git a/OPJViewer/source/imagmj2.h b/OPJViewer/source/imagmj2.h index e1737275..17cbd56b 100644 --- a/OPJViewer/source/imagmj2.h +++ b/OPJViewer/source/imagmj2.h @@ -69,7 +69,7 @@ public: } // decoding engine parameters - int m_reducefactor, m_qualitylayers, m_components; + int m_reducefactor, m_qualitylayers, m_components, m_framenum; #ifdef USE_JPWL bool m_enablejpwl; int m_expcomps, m_maxtiles; diff --git a/OPJViewer/source/opj_logo.xpm b/OPJViewer/source/opj_logo.xpm new file mode 100644 index 00000000..c64d0a7b --- /dev/null +++ b/OPJViewer/source/opj_logo.xpm @@ -0,0 +1,285 @@ +/* XPM */ +static char *opj_logo[] = { +/* columns rows colors chars-per-pixel */ +"90 61 218 2", +" c #BE3D12", +". c #BF461D", +"X c #AD5435", +"o c #B64925", +"O c #B54E2B", +"+ c #BC4620", +"@ c #BB4B25", +"# c #BC4E29", +"$ c #B5502F", +"% c #BD512C", +"& c #B45334", +"* c #B35638", +"= c #B45B3D", +"- c #BB5533", +"; c #BE5937", +": c #BC5C3D", +"> c #9C766A", +", c #AD5D42", +"< c #B55F41", +"1 c #BA5E40", +"2 c #A7634D", +"3 c #A76C57", +"4 c #AA6750", +"5 c #AC6B56", +"6 c #AA6E5A", +"7 c #A4705E", +"8 c #B46045", +"9 c #B1644B", +"0 c #BD6244", +"q c #B96448", +"w c #BC694D", +"e c #B36B53", +"r c #B26E58", +"t c #BB6C52", +"y c #B2725D", +"u c #BD7056", +"i c #BB745C", +"p c #A67566", +"a c #A57B6D", +"s c #AE7562", +"d c #AB7867", +"f c #AA7C6C", +"g c #A07E73", +"h c #AA7F71", +"j c #B37661", +"k c #B47863", +"l c #B27D6B", +"z c #BB7863", +"x c #BA7E69", +"c c #C73605", +"v c #C63A0B", +"b c #CB3300", +"n c #CA3807", +"m c #C93A0A", +"M c #C43E11", +"N c #C93E10", +"B c #C44115", +"V c #C3441A", +"C c #C4481E", +"Z c #CA4113", +"A c #C94519", +"S c #CB481C", +"D c #C24A23", +"F c #C24F28", +"G c #CD4D23", +"H c #C4522D", +"J c #CB532B", +"K c #C25632", +"L c #C35936", +"P c #C25C3B", +"I c #C85630", +"U c #CB5933", +"Y c #CB5E3A", +"T c #D05026", +"R c #CC613D", +"E c #C26343", +"W c #C46748", +"Q c #C1694C", +"! c #CD6744", +"~ c #CA6C4D", +"^ c #C37155", +"/ c #C4755B", +"( c #CB7356", +") c #C8765B", +"_ c #D06D4C", +"` c #D07253", +"' c #D47B5E", +"] c #C37B63", +"[ c #C27E68", +"{ c #C97F68", +"} c #A68175", +"| c #A48479", +" . c #AD8172", +".. c #AD8578", +"X. c #AB897D", +"o. c #B1806F", +"O. c #BA816F", +"+. c #B38373", +"@. c #B58778", +"#. c #B3897B", +"$. c #BA8472", +"%. c #BB8C7C", +"&. c #C2816B", +"*. c #CD846C", +"=. c #C38470", +"-. c #C38976", +";. c #C38D7B", +":. c #CC8973", +">. c #CF8F7A", +",. c #CB907D", +"<. c #D1937F", +"1. c #948E8C", +"2. c #9D8C86", +"3. c #9D8F89", +"4. c #96908E", +"5. c #9C918D", +"6. c #949392", +"7. c #9B9492", +"8. c #9D9997", +"9. c #9D9C9C", +"0. c #A38B83", +"q. c #AA8D83", +"w. c #A4918B", +"e. c #AC9087", +"r. c #AB938C", +"t. c #A49590", +"y. c #A29996", +"u. c #A19D9C", +"i. c #AA9790", +"p. c #AC9994", +"a. c #AC9E99", +"s. c #B18D81", +"d. c #B59084", +"f. c #B49389", +"g. c #BA9184", +"h. c #B89589", +"j. c #BA988D", +"k. c #B29B93", +"l. c #BC9C92", +"z. c #ACA19D", +"x. c #B1A19D", +"c. c #BCA39B", +"v. c #A3A3A3", +"b. c #ABA5A3", +"n. c #AEA9A7", +"m. c #ABABAA", +"M. c #B3A5A1", +"N. c #B3A9A6", +"B. c #B3ADAA", +"V. c #B9A6A0", +"C. c #B9AAA5", +"Z. c #BAADA9", +"A. c #B4B0AF", +"S. c #BAB0AD", +"D. c #B4B3B3", +"F. c #BAB5B3", +"G. c #BDB8B6", +"H. c #BBBBBB", +"J. c #C39384", +"K. c #C0978A", +"L. c #C2998B", +"P. c #CA9483", +"I. c #CD9A8A", +"U. c #C19D92", +"Y. c #D69B89", +"T. c #DB9680", +"R. c #C2A095", +"E. c #C4A69C", +"W. c #CCA193", +"Q. c #C8A599", +"!. c #CBA99D", +"~. c #C6AEA6", +"^. c #CCACA2", +"/. c #CBB2AB", +"(. c #C3B8B5", +"). c #C2BDBC", +"_. c #C9B9B3", +"`. c #D3ADA0", +"'. c #D3B4A9", +"]. c #DCB2A4", +"[. c #DEB6A8", +"{. c #D1BFB9", +"}. c #D9BEB5", +"|. c #C5C0BE", +" X c #CDC0BC", +".X c #D2C1BB", +"XX c #DDC3BB", +"oX c #E0C5BC", +"OX c #E0C8BF", +"+X c #C2C2C2", +"@X c #CBC4C2", +"#X c #CDC8C6", +"$X c #CCCBCB", +"%X c #D2C6C2", +"&X c #D1CECD", +"*X c #DDC8C1", +"=X c #DECFCA", +"-X c #D9D1CE", +";X c #D3D3D3", +":X c #D9D5D4", +">X c #DED9D7", +",X c #DBDBDB", +".;X0XwXwXwXwXrXwXwXrXrXrXrXtXrXtXrXrXrXwXrXrXrXrXrXrXrXrXrXrXrXwXrXrXwXrXrXrXtXtXrXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtX", +"tXtXtXtXrXrXrX0X,X'.S b b P l.z.M.k.w n b b g.;X,X,X,X0X0X0X0X0XwXwXwXwXwXwXwXwXwX0X0X0XwX0X0XwXwXwXwX0X0X0X0X0X0XwXwXwXwXrXrXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtX", +"tXtXtXrXrXrXwX0X:XT.m b A ] G.D.D.m.$.m b b $.$X&X.X}.XX>XOX}.oXXX c b @ 9.v.9.u., b b - 3.& b b 7 1.1.4.4.4.6.7.9.w.m b + t.v.m.p.D b b K.;X,X0XwXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtX", +"tXtXtXwX0X,X$X-.b b b i D.H.G.H.J.N b b = 9.9.5 c b B 7.9.v.y.b b m f 4.O b b 3 6.6.6.g 9 4 h u.h b b - b.m.m.s.b b N ~.;X,X0XwXrXrXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtX", +"tXtXtXwX0X,X;XE.G b b I z ] ] ] W n b H l 9.8.9 b b m e 6 r e b b # 0.y.< b b O 6 p 6 < # ; q.v.t b b 0 n.A.A.+.b b H _.;X,XwXwXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtX", +"tXtXtXwXwX,X;X#Xf.b b b b b b b b b - a.v.v.w.@ b b v b b b b b @ b.m.v.w.M b b b b b b v ..m.n.A b n g.H.H.H.4 b b [ &X,X0XwXrXrXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtX", +"tXtXtXwXwX0X:X$XZ.Q H v n b m B H E x n.m.m.q.B b v < . v N + E z m.m.m.b.e - M m v M - t k.D.m.; # - V.H.+XH.s # # K.:X,X0XwXrXrXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtX", +"tXtXtXrXwXwX,X,X$X+XG.Z.Z.B.C.S.F.H.H.H.D.D.j b b q v.b.a.n.B.H.H.+X+X+XH.H.D.Z.C.Z.Z.F.H.H.+X+XH.).H.$X&X&X;X$X#X#X:X,X0XwXrXrXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtX", +"tXtXtXrXrXwX0X,X;X#X+X+X+XH.H.+X+X+XH.H.H.D.e b n i n.m.D.H.H.+X#X$X$X+X+X+X+XH.H.H.H.+X+X+X$X&X&X&X$X;X;X;X:X;X:X,X,X0XwXwXrXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtX", +"tXtXtXtXrXrXwXwX,X,X;X;X$X$X$X;X;X&X;X$X#X+XF b v s.H.H.+X$X&X;X;X,X,X,X;X:X;X;X;X;X;X;X:X,X,X,X0X,X0X,X0X0X0X0X0X0X0XwXwXrXtXrXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtX", +"tXtXtXrXtXrXwXwX0X,X:X;X;X;X;X;X:X;X;X;X$X+XC b B k.+X+X$X$X;X,X,X0X0X0X0X0X;X,X,X,X,X,X,X,X,X0X0X0X0X0X0XwX0X0X0XwXwXrXrXrXrXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtX", +"tXtXtXtXtXrXrXrXrXwXwXwX0X0X0X0X0X0X0X,X,X:X^.^.!.$X$X;X,X,X0XwXwXwXwXwXwXwXwX0X0X0X0XwXwXwXwXwXwXrXrXwXrXrXrXrXrXrXrXrXrXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtX", +"tXtXtXtXtXtXrXrXrXrXwXwXwXwX0XwXwXwX0X0X,X:X;X$X&X&X;X,X,X0XwXwXwXrXrXrXrXrXwXwXwXwXwXwXwXrXrXrXwXrXrXrXrXrXrXrXrXrXrXtXrXtXtXrXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtX", +"tXtXtXtXtXtXtXtXtXrXrXrXrXrXrXrXrXrXwXwXwXwX0X,X0X0X0XwXwXrXrXrXrXrXrXrXrXrXrXrXrXrXrXwXrXrXrXrXrXtXrXrXrXtXrXrXrXrXrXrXrXrXrXtXtXtXrXrXtXtXtXtXrXrXtXrXrXtXrXtXrXtXtXtXtXtXtXtXtXtX", +"tXtXtXtXtXtXtXtXrXtXtXrXtXrXrXrXrXrXrXwXwXwX0XwX0XwXwXwXrXrXrXtXtXrXrXrXrXrXrXrXrXwXrXwXrXwXwXrXrXrXrXrXrXrXrXrXrXrXrXrXrXrXrXrXrXrXtXrXrXtXtXrXrXrXrXrXrXrXrXrXrXtXtXtXtXtXtXtXtXtX", +"tXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXrXrXrXwXrXrXrXrXrXrXtXrXtXrXrXrXrXrXwXwXwXwXwX0X0XwX0XwXwXwXwXwXwXwXrXwXwXwX0X0X0X0XwX0XwXwXrXrXrXwXrXwXwXwX0XwX0XwXwXwXrXrXrXrXtXtXtXtXtXtX", +"tXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXrXrXrXrXrXrXrXrXtXtXrXrXtXrXrXeX7X7X9XwXwXwX5X3X3X3X2X2X2X5X0XwXwXwXwXwX8X3X3X2X2X2X2X2X3X6X6X7XwXwXwXwXwXwX7X1XXXOXOX1X8XwXwXrXrXrXtXtXtXtXtX", +"tXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXrXtXtXtXrXrXrXwXT.T T :.,X,X-X` G G G G G G U _ J.-X,X,X,X[ G G G G G G G G G G _ >XwX0X,X&XI.R N b b b m ! `.5XwXrXrXtXtXtXtXtX", +"tXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXrXtXtXtXrXtXrXrXrXwX0X' b b ] >X,X%XJ b b b b b b b b Q {.:X;X:Xq b b b b b b b b b b Y >X0X,X-X'.^ n b b b b b m *.1XwXwXrXtXtXtXtXtX", +"tXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXrXrX0X0X%XL b b L.@X+X-.b b M L L L D b b b M V.+X(.N b b D H H H H H U U W.;X&X^.H b b n W -.-.W n b b J &XwXrXtXtXtXtXtX", +"tXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXrXwXwX0X XF b b U.+X+X[ b b D z z j P v b b N U.H.S.m b m E Q t ^ ) / ) ) /.$X$X;.m b n A %.H.H.J.N b b N .XwXwXtXtXtXtXtX", +"tXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXrXwXwX,X:X!.m b L N.D.m.* b b y v.v.v.v.p.n b M f.m.w b b D u.v.m.m.D.G.H.H.+X).g.b b B j.F.D.D.D.D.l.; F I /.0XwXrXtXtXtXtX", +"tXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXrXrXwX,X:XU.n b E B.A.n.$ b b s v.9.v.v.r.n n M r.b.1 b b D u.v.m.m.D.D.H.H.).H.k b b # M.G.D.D.D.D.Z.t w u _.0XwXtXtXtXtXtX", +"tXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXrXrXwXwX,X;X$XJ b m h b.v.i.m b M a 5.5.2.p M b c < 8.2.+ b b M o o o o # % j G.H.g.m b A M.D.D.D.B.M.M.M.M.Z.(.:X0XwXrXtXtXtXtX", +"tXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXrXrXrXrXrXwX,X,X&X(.n b M 0.v.v.s b b b b b n b b c b M u.v.g M b b b b b b b b b i G.D.0 b b 8 D.D.H.G.P n b b n b U :X,XwXtXtXtXtXtX", +"tXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXrXrXrXrXwX0X,X;X$XV.n b M w.v.9.< b b b b b b b b c H r 9.v.a n b * < < w w Q Q g.D.B.: b b r D.D.D.m.C b b b b b ) ;X0XwXrXtXtXtXtX", +"tXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXrXrXrXrX6XP.=.K.;X#X+Xx n b D v.u.7.. b b M D . D & 2 q.b.b.v.v.< b b X 6.9.9.b.m.D.D.D.D.n.# b b f D.D.D.b.= 1 * N b n !.;X,XwXtXtXtXtXtX", +"tXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXtXrXtXrXrXwXIsOpened()) WriteText(wxT("File OK")); @@ -120,218 +140,1308 @@ void OPJParseThread::ParseJ2KFile(wxFile *m_file, wxFileOffset offset, wxFileOff // position at the beginning m_file->Seek(offset, wxFromStart); - //WriteText(wxString::Format(wxT("from to %d"), length)); - // navigate the file - int m, inside_sod = 0, nmarks = 0, maxmarks = 10000, done = 0; + int m, inside_sod = 0, inside_sop = 0; + int nmarks = 0, maxmarks = 10000; unsigned char onebyte[1]; - unsigned char twobytes[2]; + 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...")); - while ((offset < length) && (!m_file->Eof())) { - done = 0; +// advancing macro +#define OPJ_ADVANCE(A) {offset += A; if (offset < length) m_file->Seek(offset, wxFromStart); else return;} - // read da marka - if (m_file->Read(twobytes, 2) != 2) + // begin search + while ((offset < length) && (!m_file->Eof())) { + + // read one byte + if (m_file->Read(&firstbyte, 1) != 1) break; - currmark = (((unsigned short int) twobytes[0]) << 8) + (unsigned short int) twobytes[1]; - // Markers cycle - for (m = 0; m < 23; m++) { + // look for 0xFF + if (firstbyte == 0xFF) { - // check the marker - if (currmark == marker_val[m]) { + // it is a possible marker + if (m_file->Read(&secondbyte, 1) != 1) + break; + else + currmark = (((unsigned short int) firstbyte) << 8) + (unsigned short int) secondbyte; - if (currmark == SOD_VAL) { + } else { - // we enter SOD - currlen = 0; - inside_sod = 1; + // 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; + } - } else if ((currmark == SOC_VAL) || (currmark == EOC_VAL) || (currmark == EPH_VAL)) - - currlen = 0; + // marker not found + if (m == J2KMARK_NUM) { + // nope, advance by one and search again + OPJ_ADVANCE(1); + continue; + } - else { + // if we are inside SOD, only some markers are allowed + if (inside_sod) { - // read length - if (m_file->Read(twobytes, 2) != 2) - break; - currlen = (((unsigned short int) twobytes[0]) << 8) + (unsigned short int) twobytes[1]; + // 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; + }*/ + } + } - // inside SOD, only some markers are allowed - if (inside_sod && (currmark != SOD_VAL) && (currmark != SOT_VAL) - && (currmark != EOC_VAL) && (currmark != SOP_VAL) && (currmark != EPH_VAL)) - break; /*randomly marker coincident data */ + // beyond this point, the marker MUST BE real - if (inside_sod && (currmark == SOT_VAL) && (lastPsot == 0)) - inside_sod = 0; /* random data coincident with SOT, but last SOT was the last one */ + // length of current marker segment + if ((currmark == SOD_VAL) || + (currmark == SOC_VAL) || + (currmark == EOC_VAL) || + (currmark == EPH_VAL)) - if (inside_sod && (currmark == SOT_VAL)) - inside_sod = 0; /* new tile part */ + // zero length markers + currlen = 0; - // 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; + 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: %s (0x%04X)"), nmarks, marker_name[m], marker_val[m]), + image, imageSel, + new OPJMarkerData(wxT("MARK"), 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::Format(wxT("%s"), 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; + + ///////// + // 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")) + ); - // append the marker - wxTreeItemId currid = m_tree->AppendItem(parentid, - wxString::Format(wxT("%03d: %s (0x%04X)"), nmarks, marker_name[m], marker_val[m]), + 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("MARK"), m_tree->m_fname.GetFullPath(), offset, offset + currlen + 1) + new OPJMarkerData(wxT("INFO")) ); - // append some info - image = m_tree->TreeCtrlIcon_File; - imageSel = image + 1; + else if ((pepb >= 0x10000000) && (pepb <= 0x1FFFFFFF)) { - // marker name - wxTreeItemId subcurrid1 = m_tree->AppendItem(currid, - wxT("*** ") + wxString::Format(wxT("%s"), marker_descr[m]) + wxT(" ***"), + 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")) ); - 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), + } 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")) ); - // give additional info on markers - switch (currmark) { - - case SOP_VAL: - { - // read packet number - if (m_file->Read(twobytes, 2) != 2) - break; - int packnum = STREAM_TO_UINT16(twobytes, 0);; - wxTreeItemId subcurrid3 = m_tree->AppendItem(currid, - wxString::Format(wxT("Pack. no. %d"), packnum), - 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; + + ///////// + // SIZ // + ///////// + case SIZ_VAL: + { + 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 (int c = 0; c < csiz; c++) { + + if (m_file->Read(&ssiz[c], 1) != 1) break; - case SIZ_VAL: - { - m_file->Seek(2, wxFromCurrent); - if (m_file->Read(fourbytes, 4) != 4) - break; - unsigned long int xsiz = STREAM_TO_UINT32(fourbytes, 0); + if (c > 0) + equaldepth = equaldepth && (ssiz[c] == ssiz[c - 1]); - if (m_file->Read(fourbytes, 4) != 4) - break; - unsigned long int ysiz = STREAM_TO_UINT32(fourbytes, 0); + if (m_file->Read(&xrsiz[c], 1) != 1) + break; - m_file->Seek(24, wxFromCurrent); - if (m_file->Read(twobytes, 2) != 2) - break; - unsigned short int csiz = STREAM_TO_UINT16(twobytes, 0); + 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 + unsigned char comment[showlen]; + + 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; + subcurrid3 = m_tree->AppendItem(currid, + wxString::Format(wxT("%.*s%s"), wxMin(showlen, currlen - 4), comment, + (((currlen - 4) > showlen) ? "..." : "")), + 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; - unsigned char ssiz = onebyte[0]; - - wxTreeItemId subcurrid3 = m_tree->AppendItem(currid, - wxString::Format(wxT("%d x %d, %d comps. @ %d bpp"), xsiz, ysiz, csiz, (ssiz + 1) & 0xEF), - image, imageSel, - new OPJMarkerData(wxT("INFO")) - ); + ttlm = onebyte[0]; + break; - } + case 2: + if (m_file->Read(twobytes, 2) != 2) + break; + ttlm = STREAM_TO_UINT16(twobytes, 0); break; - case SOT_VAL: - { + } + + switch (((stlm & 0x40) >> 6)) { + + case 0: if (m_file->Read(twobytes, 2) != 2) break; - unsigned short int isot = STREAM_TO_UINT16(twobytes, 0); + ptlm = STREAM_TO_UINT16(twobytes, 0); + break; + case 1: if (m_file->Read(fourbytes, 4) != 4) break; - unsigned long int psot = STREAM_TO_UINT32(fourbytes, 0); + ptlm = STREAM_TO_UINT32(fourbytes, 0); + break; - if (m_file->Read(onebyte, 1) != 1) - break; - unsigned char tpsot = onebyte[0]; + } + + 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; - 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")) - ); + cspod = onebyte[0]; + } else { + if (m_file->Read(twobytes, 2) != 2) + break; + cspod = STREAM_TO_UINT16(twobytes, 0); + } - lastPsot = psot; - lastsotpos = offset; - }; + if (m_file->Read(twobytes, 2) != 2) break; + unsigned short int lyepod = STREAM_TO_UINT16(twobytes, 0); - case CME_VAL: - { - #define showlen 25 - unsigned char comment[showlen]; + if (m_file->Read(onebyte, 1) != 1) + break; + unsigned char repod = onebyte[0]; - m_file->Seek(2, wxFromCurrent); - if (m_file->Read(comment, showlen) != showlen) + 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); + } - wxTreeItemId subcurrid3 = m_tree->AppendItem(currid, - wxString::Format(wxT("%.*s%s"), wxMin(showlen, currlen - 4), comment, - (((currlen - 4) > showlen) ? "..." : "")), - image, imageSel, - new OPJMarkerData(wxT("INFO")) - ); - } + 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; } - - - // increment number of markers - nmarks++; - if (nmarks >= maxmarks) - break; + subcurrid4 = m_tree->AppendItem(subcurrid3, + text, + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + } - // increment offset - if (currmark == SOD_VAL) - offset += lastPsot - (offset - lastsotpos); - else - offset += (2 + currlen); + } + break; - m_file->Seek(offset, wxFromStart); - done = 1; + ///////// + // SOD // + ///////// + case SOD_VAL: + { + inside_sod = 1; + }; + break; - break; - } + default: + break; + } - - if (done) - continue; - else { - offset++; - m_file->Seek(offset, wxFromStart); + + // 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/OPJViewer/source/wxjp2parser.cpp b/OPJViewer/source/wxjp2parser.cpp index c929418d..46698bda 100644 --- a/OPJViewer/source/wxjp2parser.cpp +++ b/OPJViewer/source/wxjp2parser.cpp @@ -484,7 +484,7 @@ int OPJParseThread::box_handler_function(int boxtype, wxFile *fileid, wxFileOffs ); wxString text; - for (int s = 0; s < sample_count; s++) { + for (unsigned int s = 0; s < sample_count; s++) { fileid->Read(&entry_size, sizeof(unsigned long int)); entry_size = BYTE_SWAP4(entry_size); @@ -844,15 +844,15 @@ int OPJParseThread::jpeg2000parse(wxFile *fileid, wxFileOffset filepoint, wxFile wxTreeItemId parentid, int level, char *scansign, unsigned long int *scanpoint) { unsigned long int LBox = 0x00000000; - int LBox_read; + //int LBox_read; char TBox[5] = "\0\0\0\0"; - int TBox_read; + //int TBox_read; int8byte XLBox = 0x0000000000000000; - int XLBox_read; + //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]; + unsigned char /*onebyte[1], twobytes[2],*/ fourbytes[4]; /* cycle all over the file */ box_num = 0; -- cgit v1.2.3