Added the OPJViewer Module (/OPJViewer), developed by Giuseppe Baruffa of the University of Perugia
This commit is contained in:
parent
7cb2194c8e
commit
e841b13166
@ -5,6 +5,9 @@ What's New for OpenJPEG
|
||||
! : changed
|
||||
+ : added
|
||||
|
||||
February 22, 2007
|
||||
+ [FOD] Added the OPJViewer Module (/OPJViewer), developed by Giuseppe Baruffa of the university of Perugia
|
||||
|
||||
February 21, 2007
|
||||
+ [FOD] Algorithmic optimizations in t1.c, thanks to Guido J. !
|
||||
|
||||
|
206
OPJViewer/OPJViewer.dsp
Normal file
206
OPJViewer/OPJViewer.dsp
Normal file
@ -0,0 +1,206 @@
|
||||
# Microsoft Developer Studio Project File - Name="OPJViewer" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Console Application" 0x0103
|
||||
|
||||
CFG=OPJVIEWER - WIN32 RELEASE
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "OPJViewer.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "OPJViewer.mak" CFG="OPJVIEWER - WIN32 RELEASE"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "OPJViewer - Win32 Release" (based on "Win32 (x86) Console Application")
|
||||
!MESSAGE "OPJViewer - Win32 Debug" (based on "Win32 (x86) Console Application")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=cl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "OPJViewer - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "W32Release"
|
||||
# PROP Intermediate_Dir "W32Release"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||
# ADD CPP /nologo /G6 /MD /GX /O2 /I "c:\programmi\wxWidgets-2.8.0\lib\vc_lib\msw" /I "c:\programmi\wxWidgets-2.8.0\include" /I ".." /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_WINDOWS" /D WINVER=0x400 /D "_MT" /D wxUSE_GUI=1 /D "wxUSE_LIBOPENJPEG" /D "OPJ_STATIC" /D "USE_JPWL" /FR /FD /c
|
||||
# SUBTRACT CPP /YX
|
||||
# ADD BASE RSC /l 0x410 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /i "c:\programmi\wxWidgets-2.8.0\include" /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib rpcrt4.lib wsock32.lib wxzlib.lib wxregex.lib wxpng.lib wxjpeg.lib wxbase28.lib wxmsw28_core.lib wxmsw28_html.lib wxmsw28_adv.lib wxmsw28_core.lib wxbase28.lib wxtiff.lib wxjpeg.lib wxpng.lib wxzlib.lib wxregex.lib wxexpat.lib LibOpenJPEG_JPWL.lib /nologo /subsystem:windows /machine:I386 /nodefaultlib:"libcmt.lib" /libpath:"c:\programmi\wxWidgets-2.8.0\lib\vc_lib" /libpath:"..\jpwl\Release" /IGNORE:4089
|
||||
# SUBTRACT LINK32 /pdb:none
|
||||
|
||||
!ELSEIF "$(CFG)" == "OPJViewer - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "OPJViewer___Win32_Debug"
|
||||
# PROP BASE Intermediate_Dir "OPJViewer___Win32_Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "W32Debug"
|
||||
# PROP Intermediate_Dir "W32Debug"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MDd /Gm /GX /Zi /Od /I "C:\Programmi\wxWidgets-2.8.0\INCLUDE" /I "c:\programmi\wxWidgets-2.8.0\lib\vc_lib\msw" /I "c:\programmi\wxWidgets-2.8.0\include" /I ".." /D "_DEBUG" /D "__WXDEBUG__" /D WXDEBUG=1 /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_WINDOWS" /D WINVER=0x400 /D "_MT" /D wxUSE_GUI=1 /D "wxUSE_LIBOPENJPEG" /D "OPJ_STATIC" /D "USE_JPWL" /FR /FD /GZ /c
|
||||
# SUBTRACT CPP /YX
|
||||
# ADD BASE RSC /l 0x410 /d "_DEBUG"
|
||||
# ADD RSC /l 0x410 /i "c:\programmi\wxWidgets-2.8.0\include" /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib rpcrt4.lib wsock32.lib wxzlibd.lib wxregexd.lib wxpngd.lib wxjpegd.lib wxtiffd.lib wxbase28d.lib wxmsw28d_core.lib wxmsw28d_html.lib wxmsw28d_adv.lib LibOpenJPEG_JPWL.lib /nologo /subsystem:windows /debug /machine:I386 /nodefaultlib:"libcmtd.lib" /pdbtype:sept /libpath:"c:\programmi\wxWidgets-2.8.0\lib\vc_lib" /libpath:"..\jpwl\Debug"
|
||||
# SUBTRACT LINK32 /pdb:none
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "OPJViewer - Win32 Release"
|
||||
# Name "OPJViewer - Win32 Debug"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\source\imagj2k.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\source\imagjp2.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\source\imagmj2.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\source\OPJViewer.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\source\wxj2kparser.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\source\wxjp2parser.cpp
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\source\imagj2k.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\source\imagjp2.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\source\imagmj2.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\source\OPJViewer.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Resource Files"
|
||||
|
||||
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\source\icon1.xpm
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\source\icon2.xpm
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\source\icon3.xpm
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\source\icon4.xpm
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\source\icon5.xpm
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\source\OPJViewer.ico
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\source\OPJViewer.rc
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\source\OPJViewer16.xpm
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "JPWL"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\jpwl\crc.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\jpwl\crc.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\jpwl\jpwl.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\jpwl\jpwl.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\jpwl\jpwl_lib.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\jpwl\rs.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\jpwl\rs.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# End Target
|
||||
# End Project
|
44
OPJViewer/OPJViewer.dsw
Normal file
44
OPJViewer/OPJViewer.dsw
Normal file
@ -0,0 +1,44 @@
|
||||
Microsoft Developer Studio Workspace File, Format Version 6.00
|
||||
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "LibOpenJPEG_JPWL"=..\jpwl\LibOpenJPEG_JPWL.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "OPJViewer"=.\OPJViewer.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name LibOpenJPEG_JPWL
|
||||
End Project Dependency
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Global:
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<3>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
34
OPJViewer/OPJViewer.iss
Normal file
34
OPJViewer/OPJViewer.iss
Normal file
@ -0,0 +1,34 @@
|
||||
; 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.1 alpha
|
||||
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=OPJViewer01alpha_setup
|
||||
Compression=lzma
|
||||
SolidCompression=yes
|
||||
|
||||
[Languages]
|
||||
Name: english; MessagesFile: compiler:Default.isl
|
||||
|
||||
[Tasks]
|
||||
Name: desktopicon; Description: {cm:CreateDesktopIcon}; GroupDescription: {cm:AdditionalIcons}; Flags: unchecked
|
||||
|
||||
[Files]
|
||||
Source: W32Release\OPJViewer.exe; DestDir: {app}; Flags: ignoreversion
|
||||
; NOTE: Don't use "Flags: ignoreversion" on any shared system files
|
||||
|
||||
[Icons]
|
||||
Name: {group}\OPJViewer; Filename: {app}\OPJViewer.exe
|
||||
Name: {group}\{cm:UninstallProgram,OPJViewer}; Filename: {uninstallexe}
|
||||
Name: {userdesktop}\OPJViewer; Filename: {app}\OPJViewer.exe; Tasks: desktopicon
|
||||
|
||||
[Run]
|
||||
Filename: {app}\OPJViewer.exe; Description: {cm:LaunchProgram,OPJViewer}; Flags: nowait postinstall skipifsilent
|
1849
OPJViewer/source/OPJViewer.cpp
Normal file
1849
OPJViewer/source/OPJViewer.cpp
Normal file
File diff suppressed because it is too large
Load Diff
469
OPJViewer/source/OPJViewer.h
Normal file
469
OPJViewer/source/OPJViewer.h
Normal file
@ -0,0 +1,469 @@
|
||||
/*
|
||||
* 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
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#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 <wx/filename.h>
|
||||
#include <wx/busyinfo.h>
|
||||
#include <wx/cmdline.h>
|
||||
#include <wx/file.h>
|
||||
#include "wx/notebook.h"
|
||||
|
||||
#include "libopenjpeg\openjpeg.h"
|
||||
|
||||
#include "imagj2k.h"
|
||||
#include "imagjp2.h"
|
||||
#include "imagmj2.h"
|
||||
|
||||
#define USE_GENERIC_TREECTRL 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_NAME wxT("OpenJPEG Viewer")
|
||||
#define OPJ_APPLICATION_VERSION wxT("0.1 alpha")
|
||||
#define OPJ_APPLICATION_TITLEBAR OPJ_APPLICATION_NAME wxT(" ") OPJ_APPLICATION_VERSION
|
||||
#define OPJ_APPLICATION_COPYRIGHT wxT("(C) 2007, Giuseppe Baruffa")
|
||||
|
||||
#define OPJ_CANVAS_BORDER 10
|
||||
#define OPJ_CANVAS_COLOUR *wxWHITE
|
||||
|
||||
class OPJDecoThread;
|
||||
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);
|
||||
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;
|
||||
|
||||
// crit section protects access to all of the arrays below
|
||||
wxCriticalSection m_deco_critsect, m_parse_critsect;
|
||||
|
||||
// semaphore used to wait for the threads to exit, see OPJFrame::OnQuit()
|
||||
wxSemaphore m_deco_semAllDone, m_parse_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;
|
||||
|
||||
// the list of all filenames written in the command line
|
||||
wxArrayString m_filelist;
|
||||
|
||||
// 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) { wxMutexGuiEnter(); wxLogMessage(text); wxMutexGuiLeave();}
|
||||
OPJDecoThread *CreateDecoThread(void);
|
||||
|
||||
wxBitmap m_image;
|
||||
wxFileName m_fname;
|
||||
|
||||
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;
|
||||
|
||||
// private methods and variables
|
||||
private:
|
||||
wxString m_desc;
|
||||
wxString m_filestring;
|
||||
};
|
||||
|
||||
|
||||
class OPJMarkerTree : public wxTreeCtrl
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
TreeCtrlIcon_File,
|
||||
TreeCtrlIcon_FileSelected,
|
||||
TreeCtrlIcon_Folder,
|
||||
TreeCtrlIcon_FolderSelected,
|
||||
TreeCtrlIcon_FolderOpened
|
||||
};
|
||||
|
||||
OPJMarkerTree() { };
|
||||
OPJMarkerTree(wxWindow *parent, wxFileName fname, wxString name, const wxWindowID id,
|
||||
const wxPoint& pos, const wxSize& size,
|
||||
long style);
|
||||
virtual ~OPJMarkerTree(){};
|
||||
OPJParseThread *CreateParseThread(wxTreeItemId parentid = 0x00);
|
||||
void WriteText(const wxString& text) { wxMutexGuiEnter(); wxLogMessage(text); wxMutexGuiLeave(); }
|
||||
|
||||
wxFileName m_fname;
|
||||
wxTextCtrl *m_peektextCtrl;
|
||||
|
||||
/*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& event);
|
||||
void OnAbout(wxCommandEvent& WXUNUSED(event));
|
||||
void OnFileOpen(wxCommandEvent& WXUNUSED(event));
|
||||
void OnQuit(wxCommandEvent& WXUNUSED(event));
|
||||
void OnToggleWindow(wxCommandEvent& WXUNUSED(event));
|
||||
void OnSashDrag(wxSashEvent& event);
|
||||
void OpenFiles(wxArrayString paths, wxArrayString filenames);
|
||||
void OnNotebook(wxNotebookEvent& event);
|
||||
|
||||
OPJMarkerTreeHash m_treehash;
|
||||
OPJChildFrameHash m_childhash;
|
||||
wxSashLayoutWindow* markerTreeWindow;
|
||||
wxSashLayoutWindow* loggingWindow;
|
||||
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;
|
||||
|
||||
DECLARE_EVENT_TABLE()
|
||||
};
|
||||
|
||||
#define SASHTEST_QUIT wxID_EXIT
|
||||
#define SASHTEST_NEW_WINDOW 2
|
||||
#define SASHTEST_REFRESH 3
|
||||
#define SASHTEST_CHILD_QUIT 4
|
||||
#define SASHTEST_ABOUT wxID_ABOUT
|
||||
#define SASHTEST_TOGGLE_WINDOW 6
|
||||
|
||||
#define ID_WINDOW_TOP 100
|
||||
#define ID_WINDOW_LEFT1 101
|
||||
#define ID_WINDOW_LEFT2 102
|
||||
#define ID_WINDOW_BOTTOM 103
|
||||
|
||||
// menu and control ids
|
||||
enum
|
||||
{
|
||||
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 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);
|
||||
|
||||
};
|
||||
|
||||
#endif //__OPJ_VIEWER_H__
|
BIN
OPJViewer/source/OPJViewer.ico
Normal file
BIN
OPJViewer/source/OPJViewer.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
2
OPJViewer/source/OPJViewer.rc
Normal file
2
OPJViewer/source/OPJViewer.rc
Normal file
@ -0,0 +1,2 @@
|
||||
OPJViewer16 ICON OPJViewer.ico
|
||||
#include "wx/msw/wx.rc"
|
26
OPJViewer/source/OPJViewer16.xpm
Normal file
26
OPJViewer/source/OPJViewer16.xpm
Normal file
@ -0,0 +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"
|
||||
};
|
79
OPJViewer/source/icon1.xpm
Normal file
79
OPJViewer/source/icon1.xpm
Normal file
@ -0,0 +1,79 @@
|
||||
/* XPM */
|
||||
static char *icon1_xpm[] = {
|
||||
/* columns rows colors chars-per-pixel */
|
||||
"32 32 41 1",
|
||||
"> c #97C4E7",
|
||||
"# c #4381AA",
|
||||
"d c #FFFFFF",
|
||||
"< c #71B2DE",
|
||||
"+ c #538BB1",
|
||||
"& c #D1E5F5",
|
||||
"q c #63B3DE",
|
||||
"6 c #F1F4F7",
|
||||
"* c #CAE1F3",
|
||||
"y c #7AC4E5",
|
||||
"= c #C3DDF1",
|
||||
"X c #74A1BD",
|
||||
"- c #BCD9EF",
|
||||
"5 c #619BC4",
|
||||
"3 c #E6EAF1",
|
||||
"2 c #4B8EBF",
|
||||
"o c #6B97B6",
|
||||
". c #4B82A8",
|
||||
" c None",
|
||||
"w c #54A6D8",
|
||||
"1 c #71A8D1",
|
||||
", c #85BBE2",
|
||||
"t c #EFF6FC",
|
||||
"7 c #DEEDF8",
|
||||
"@ c #4388B4",
|
||||
"a c #F7FBFD",
|
||||
"$ c #D7E0E9",
|
||||
"r c #FAFCFE",
|
||||
"4 c #DAEAF7",
|
||||
"e c #E9F3FA",
|
||||
"0 c #76BAE2",
|
||||
"% c #7FA6C0",
|
||||
"s c #FDFDFE",
|
||||
"O c #5896BE",
|
||||
"p c #B6D5EE",
|
||||
"8 c #87ABC3",
|
||||
": c #A5CCEA",
|
||||
"9 c #E5F0F9",
|
||||
"; c #AFD1EC",
|
||||
"i c #F4F9FD",
|
||||
"u c #8FB0C3",
|
||||
/* pixels */
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" .XXXooOO++@#$ ",
|
||||
" %&*=-;:>>,<123 ",
|
||||
" %4&*=-;:>>,1>56 ",
|
||||
" %74&*=-;:>>1*>56 ",
|
||||
" 89700qqqqwq1e*>X ",
|
||||
" 8e974&*=-;:1re*>8 ",
|
||||
" 8te974&*=-;11111# ",
|
||||
" 8tty000qqqqqww>,+ ",
|
||||
" uitte974&*=-p:>>+ ",
|
||||
" uaitte974&*=-p:>O ",
|
||||
" uaayyyy000qqqqp:O ",
|
||||
" uraaitte974&*=-po ",
|
||||
" urraaitte974&*=-o ",
|
||||
" usryyyyyyy000q*=X ",
|
||||
" ussrraaitte974&*X ",
|
||||
" udssrraaitte974&X ",
|
||||
" uddyyyyyyyyyy074% ",
|
||||
" udddssrraaitte97% ",
|
||||
" uddddssrraaitte9% ",
|
||||
" udddddssrraaitte8 ",
|
||||
" uddddddssrraaitt8 ",
|
||||
" uuuuuuuuuuuuuu88u ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" "
|
||||
};
|
53
OPJViewer/source/icon2.xpm
Normal file
53
OPJViewer/source/icon2.xpm
Normal file
@ -0,0 +1,53 @@
|
||||
/* XPM */
|
||||
static char *icon2_xpm[] = {
|
||||
/* columns rows colors chars-per-pixel */
|
||||
"32 32 15 1",
|
||||
". c Black",
|
||||
"O c #97C4E7",
|
||||
"$ c #63B3DE",
|
||||
"@ c #CAE1F3",
|
||||
"; c #7AC4E5",
|
||||
"* c #74A1BD",
|
||||
"+ c #619BC4",
|
||||
"o c #4B8EBF",
|
||||
" c None",
|
||||
"% c #54A6D8",
|
||||
"= c #FAFCFE",
|
||||
"& c #E9F3FA",
|
||||
"# c #76BAE2",
|
||||
"X c #C00000",
|
||||
"- c #87ABC3",
|
||||
/* pixels */
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ............. ",
|
||||
" .XXXXXXXXXX.o. ",
|
||||
" .XXXXXXXXXX.O+. ",
|
||||
" .XXXXXXXXXX.@O+. ",
|
||||
" .XX##$$$$%$.&@O* ",
|
||||
" .XXXXXXXXXX.=&@O- ",
|
||||
" .XXXXXXXXXX...... ",
|
||||
" .XX;###$$$$$%%XX. ",
|
||||
" .XXXXXXXXXXXXXXX. ",
|
||||
" .XXXXXXXXXXXXXXX. ",
|
||||
" .XX;;;;###$$$$XX. ",
|
||||
" .XXXXXXXXXXXXXXX. ",
|
||||
" .XXXXXXXXXXXXXXX. ",
|
||||
" .XX;;;;;;;###$XX. ",
|
||||
" .XXXXXXXXXXXXXXX. ",
|
||||
" .XXXXXXXXXXXXXXX. ",
|
||||
" .XX;;;;;;;;;;#XX. ",
|
||||
" .XXXXXXXXXXXXXXX. ",
|
||||
" .XXXXXXXXXXXXXXX. ",
|
||||
" .XXXXXXXXXXXXXXX. ",
|
||||
" .XXXXXXXXXXXXXXX. ",
|
||||
" ................. ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" "
|
||||
};
|
79
OPJViewer/source/icon3.xpm
Normal file
79
OPJViewer/source/icon3.xpm
Normal file
@ -0,0 +1,79 @@
|
||||
/* XPM */
|
||||
static char *icon3_xpm[] = {
|
||||
/* columns rows colors chars-per-pixel */
|
||||
"32 32 41 1",
|
||||
"6 c #EDF2FB",
|
||||
"- c #AAC1E8",
|
||||
": c #B9CDED",
|
||||
"X c #295193",
|
||||
", c #C6D6F0",
|
||||
"a c #4A7CCE",
|
||||
"u c #779DDB",
|
||||
"y c #7FA2DD",
|
||||
"$ c #3263B4",
|
||||
"5 c #EAF0FA",
|
||||
". c #2D59A3",
|
||||
"o c #6E96D8",
|
||||
"* c #356AC1",
|
||||
"r c #F7F9FD",
|
||||
"> c #BED0EE",
|
||||
"3 c #E1E9F7",
|
||||
"7 c #F0F5FC",
|
||||
"< c #CBD9F1",
|
||||
"2 c #DAE5F6",
|
||||
"# c #3161B1",
|
||||
" c None",
|
||||
"0 c #FDFEFF",
|
||||
"= c #9FB9E5",
|
||||
"e c #AEC5EA",
|
||||
"t c #89A9DF",
|
||||
"q c #98B5E4",
|
||||
"p c #5584D1",
|
||||
"d c #3A70CA",
|
||||
"@ c #305FAC",
|
||||
"i c #5D89D3",
|
||||
"1 c #D2DFF4",
|
||||
"% c #3366B9",
|
||||
"9 c #FAFCFE",
|
||||
"8 c #F5F8FD",
|
||||
"s c #4075CC",
|
||||
"O c #638ED5",
|
||||
"w c #90AFE2",
|
||||
"& c #3467BC",
|
||||
"+ c #2F5DA9",
|
||||
"; c #B3C8EB",
|
||||
"4 c #E5EDF9",
|
||||
/* pixels */
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ......X ",
|
||||
" .oooooO+ ",
|
||||
" .ooooooo. ",
|
||||
" .+@@@##$%%&&&&&****. ",
|
||||
" .=-;:>,<12345678900. ",
|
||||
" .q=-;:>,<1234567890. ",
|
||||
" .wq=-e:>,<12345678r. ",
|
||||
" .twq=-e:>,<12345678. ",
|
||||
" .ytwq=-e:>,<1234567. ",
|
||||
" .uytwq=-e:>,<123456. ",
|
||||
" .ouytwq=-e:>,<12345. ",
|
||||
" .Oouytwq=-e;>,<1234. ",
|
||||
" .iOouytwq=-e;>,<123. ",
|
||||
" .piOouytwq=-e;>,<12. ",
|
||||
" .apiOouytwq=-e;>,<1. ",
|
||||
" .sapiOouytwq=-e;>,<. ",
|
||||
" .dsapiOouytwq=-e;>,. ",
|
||||
" ...................# ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" "
|
||||
};
|
43
OPJViewer/source/icon4.xpm
Normal file
43
OPJViewer/source/icon4.xpm
Normal file
@ -0,0 +1,43 @@
|
||||
/* XPM */
|
||||
static char *icon4_xpm[] = {
|
||||
/* columns rows colors chars-per-pixel */
|
||||
"32 32 5 1",
|
||||
". c Black",
|
||||
"o c #8399B4",
|
||||
"X c #8DA0B9",
|
||||
" c None",
|
||||
"O c #800000",
|
||||
/* pixels */
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ....... ",
|
||||
" .XXXXXo. ",
|
||||
" .XXXXXXX. ",
|
||||
" .................... ",
|
||||
" .OOOOOOOOOOOOOOOOOO. ",
|
||||
" .OOOOOOOOOOOOOOOOOO. ",
|
||||
" .OOOOOOOOOOOOOOOOOO. ",
|
||||
" .OOOOOOOOOOOOOOOOOO. ",
|
||||
" .OOOOOOOOOOOOOOOOOO. ",
|
||||
" .OOOOOOOOOOOOOOOOOO. ",
|
||||
" .OOOOOOOOOOOOOOOOOO. ",
|
||||
" .OOOOOOOOOOOOOOOOOO. ",
|
||||
" .OOOOOOOOOOOOOOOOOO. ",
|
||||
" .OOOOOOOOOOOOOOOOOO. ",
|
||||
" .OOOOOOOOOOOOOOOOOO. ",
|
||||
" .OOOOOOOOOOOOOOOOOO. ",
|
||||
" .OOOOOOOOOOOOOOOOOO. ",
|
||||
" .................... ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" "
|
||||
};
|
79
OPJViewer/source/icon5.xpm
Normal file
79
OPJViewer/source/icon5.xpm
Normal file
@ -0,0 +1,79 @@
|
||||
/* XPM */
|
||||
static char *icon5_xpm[] = {
|
||||
/* columns rows colors chars-per-pixel */
|
||||
"32 32 41 1",
|
||||
"0 c #AAC1E8",
|
||||
"q c #B9CDED",
|
||||
"X c #295193",
|
||||
"e c #C6D6F0",
|
||||
"a c #4A7CCE",
|
||||
"& c #779DDB",
|
||||
"* c #7FA2DD",
|
||||
"2 c #EAF0FA",
|
||||
"@ c #2D59A3",
|
||||
"o c #6E96D8",
|
||||
"y c #356AC1",
|
||||
"d c #214279",
|
||||
"w c #BED0EE",
|
||||
"= c #85A7DF",
|
||||
"< c #E1E9F7",
|
||||
"3 c #F0F5FC",
|
||||
"s c #CBD9F1",
|
||||
", c #DAE5F6",
|
||||
"7 c #3161B1",
|
||||
" c None",
|
||||
". c #274D8B",
|
||||
"6 c #FDFEFF",
|
||||
"i c #E7EEF9",
|
||||
"9 c #9FB9E5",
|
||||
"- c #89A9DF",
|
||||
"8 c #98B5E4",
|
||||
"$ c #5584D1",
|
||||
"+ c #3569BF",
|
||||
"% c #305FAC",
|
||||
"O c #5D89D3",
|
||||
"> c #D2DFF4",
|
||||
"p c #3366B9",
|
||||
"5 c #FAFCFE",
|
||||
"4 c #F5F8FD",
|
||||
"t c #4075CC",
|
||||
"u c #638ED5",
|
||||
"r c #CEDCF2",
|
||||
"; c #90AFE2",
|
||||
"# c #2F5DA9",
|
||||
": c #B3C8EB",
|
||||
"1 c #E5EDF9",
|
||||
/* pixels */
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ......X ",
|
||||
" XoooooO. ",
|
||||
" Xoooooo+. ",
|
||||
" Xooooooo@XXXXXXXXXX# ",
|
||||
" Xoooooooooooooooooo# ",
|
||||
" Xoooooooooooooooooo# ",
|
||||
" Xoo$################### ",
|
||||
" Xoo%O&*=-;:>,<123445667 ",
|
||||
" XooX890:qwer>,<123445q# ",
|
||||
" Xoty;890:qwer>,<12344# ",
|
||||
" Xo%u-;890:qwer>,<i234# ",
|
||||
" XoX&*-;890:qwer>,<i2r# ",
|
||||
" Xtpo&*-;890:qwer>,<i# ",
|
||||
" X%auo&*-;890:qwer>,<# ",
|
||||
" XX$Ouo&*-;890:qwer>s# ",
|
||||
" d%a$Ouo&*-;890:qwer# ",
|
||||
" d+ta$Ouo&*-;890:qwe# ",
|
||||
" d..................# ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" "
|
||||
};
|
312
OPJViewer/source/imagj2k.cpp
Normal file
312
OPJViewer/source/imagj2k.cpp
Normal file
@ -0,0 +1,312 @@
|
||||
/*
|
||||
* 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: imagj2k.cpp
|
||||
// Purpose: wxImage JPEG 2000 codestream handler
|
||||
// Author: Giuseppe Baruffa - based on imagjpeg.cpp, Vaclav Slavik
|
||||
// RCS-ID: $Id: imagj2k.cpp,v 0.00 2007/02/08 23:59: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 "imagj2k.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
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// wxJ2KHandler
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
IMPLEMENT_DYNAMIC_CLASS(wxJ2KHandler,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
|
||||
|
||||
/* sample error callback expecting a FILE* client object */
|
||||
void j2k_error_callback(const char *msg, void *client_data) {
|
||||
char m_msg[MAX_MESSAGE_LEN];
|
||||
int message_len = strlen(msg) - 1;
|
||||
if (msg[message_len] != '\n')
|
||||
message_len = MAX_MESSAGE_LEN;
|
||||
sprintf(m_msg, "[ERROR] %.*s", message_len, msg);
|
||||
wxMutexGuiEnter();
|
||||
wxLogMessage(m_msg);
|
||||
wxMutexGuiLeave();
|
||||
}
|
||||
/* sample warning callback expecting a FILE* client object */
|
||||
void j2k_warning_callback(const char *msg, void *client_data) {
|
||||
char m_msg[MAX_MESSAGE_LEN];
|
||||
int message_len = strlen(msg) - 1;
|
||||
if (msg[message_len] != '\n')
|
||||
message_len = MAX_MESSAGE_LEN;
|
||||
sprintf(m_msg, "[WARNING] %.*s", message_len, msg);
|
||||
wxMutexGuiEnter();
|
||||
wxLogMessage(m_msg);
|
||||
wxMutexGuiLeave();
|
||||
}
|
||||
/* sample debug callback expecting no client object */
|
||||
void j2k_info_callback(const char *msg, void *client_data) {
|
||||
char m_msg[MAX_MESSAGE_LEN];
|
||||
int message_len = strlen(msg) - 1;
|
||||
if (msg[message_len] != '\n')
|
||||
message_len = MAX_MESSAGE_LEN;
|
||||
sprintf(m_msg, "[INFO] %.*s", message_len, msg);
|
||||
wxMutexGuiEnter();
|
||||
wxLogMessage(m_msg);
|
||||
wxMutexGuiLeave();
|
||||
}
|
||||
|
||||
// load the j2k codestream
|
||||
bool wxJ2KHandler::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;
|
||||
FILE *fsrc = NULL;
|
||||
unsigned char *src = NULL;
|
||||
unsigned char *ptr;
|
||||
int file_length;
|
||||
int shiftbpp;
|
||||
|
||||
// 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 = j2k_error_callback;
|
||||
event_mgr.warning_handler = j2k_warning_callback;
|
||||
event_mgr.info_handler = j2k_info_callback;
|
||||
|
||||
/* set decoding parameters to default values */
|
||||
opj_set_default_decoder_parameters(¶meters);
|
||||
|
||||
/* prepare parameters */
|
||||
parameters.decod_format = J2K_CFMT;
|
||||
parameters.cod_format = BMP_DFMT;
|
||||
|
||||
/* JPWL only */
|
||||
#ifdef USE_JPWL
|
||||
parameters.jpwl_exp_comps = 3;
|
||||
parameters.jpwl_max_tiles = 100;
|
||||
parameters.jpwl_correct = true;
|
||||
#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();
|
||||
|
||||
/* get data */
|
||||
stream.SeekI(0, wxFromStart);
|
||||
src = (unsigned char *) malloc(file_length);
|
||||
stream.Read(src, file_length);
|
||||
|
||||
/* 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, file_length);
|
||||
|
||||
/* decode the stream and fill the image structure */
|
||||
opjimage = opj_decode(dinfo, cio);
|
||||
if (!opjimage) {
|
||||
wxMutexGuiEnter();
|
||||
wxLogError("J2K: failed to decode image!");
|
||||
wxMutexGuiLeave();
|
||||
opj_destroy_decompress(dinfo);
|
||||
opj_cio_close(cio);
|
||||
opj_image_destroy(opjimage);
|
||||
free(src);
|
||||
return false;
|
||||
}
|
||||
|
||||
// check image components
|
||||
if ((opjimage->numcomps != 1) && (opjimage->numcomps != 3)) {
|
||||
wxMutexGuiEnter();
|
||||
wxLogError("J2K: weird number of components");
|
||||
wxMutexGuiLeave();
|
||||
opj_destroy_decompress(dinfo);
|
||||
opj_cio_close(cio);
|
||||
free(src);
|
||||
return false;
|
||||
}
|
||||
|
||||
// check image depth (only on the first one, for now)
|
||||
shiftbpp = opjimage->comps[0].prec - 8;
|
||||
|
||||
// prepare image size
|
||||
image->Create(opjimage->comps[0].w, opjimage->comps[0].h, true );
|
||||
|
||||
// access image raw data
|
||||
image->SetMask( false );
|
||||
ptr = image->GetData();
|
||||
|
||||
// RGB color picture
|
||||
if (opjimage->numcomps == 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 {
|
||||
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 (opjimage->numcomps == 1) {
|
||||
int row, col;
|
||||
int *y = opjimage->comps[0].data;
|
||||
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 {
|
||||
for (row = 0; row < opjimage->comps[0].h; row++) {
|
||||
for (col = 0; col < opjimage->comps[0].w; col++) {
|
||||
|
||||
*(ptr++) = *(y);
|
||||
*(ptr++) = *(y);
|
||||
*(ptr++) = *(y++);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
wxMutexGuiEnter();
|
||||
wxLogMessage(wxT("J2K: image loaded."));
|
||||
wxMutexGuiLeave();
|
||||
|
||||
/* close openjpeg structs */
|
||||
opj_destroy_decompress(dinfo);
|
||||
opj_cio_close(cio);
|
||||
opj_image_destroy(opjimage);
|
||||
free(src);
|
||||
|
||||
if (!image->Ok())
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
// save the j2k codestream
|
||||
bool wxJ2KHandler::SaveFile( wxImage *image, wxOutputStream& stream, bool verbose )
|
||||
{
|
||||
wxLogError(wxT("J2K: Couldn't save image -> not implemented."));
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef __VISUALC__
|
||||
#pragma warning(default:4611)
|
||||
#endif /* VC++ */
|
||||
|
||||
// recognize the 0xFF4F JPEG 2000 SOC marker
|
||||
bool wxJ2KHandler::DoCanRead( wxInputStream& stream )
|
||||
{
|
||||
unsigned char hdr[2];
|
||||
|
||||
if ( !stream.Read(hdr, WXSIZEOF(hdr)) )
|
||||
return false;
|
||||
|
||||
return hdr[0] == 0xFF && hdr[1] == 0x4F;
|
||||
}
|
||||
|
||||
#endif // wxUSE_STREAMS
|
||||
|
||||
#endif // wxUSE_LIBOPENJPEG
|
75
OPJViewer/source/imagj2k.h
Normal file
75
OPJViewer/source/imagj2k.h
Normal file
@ -0,0 +1,75 @@
|
||||
/*
|
||||
* 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: imagj2k.h
|
||||
// Purpose: wxImage JPEG 2000 raw codestream handler
|
||||
// Author: G. Baruffa - based on imagjpeg.h, Vaclav Slavik
|
||||
// RCS-ID: $Id: imagj2k.h,v 0.0 2007/02/08 23:45:00 VZ Exp $
|
||||
// Copyright: (c) Giuseppe Baruffa
|
||||
// Licence: wxWindows licence
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _WX_IMAGJ2K_H_
|
||||
#define _WX_IMAGJ2K_H_
|
||||
|
||||
#include "wx/defs.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// wxJ2KHandler
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#if wxUSE_LIBOPENJPEG
|
||||
|
||||
#include "wx/image.h"
|
||||
|
||||
#define wxBITMAP_TYPE_J2K 47
|
||||
|
||||
class WXDLLEXPORT wxJ2KHandler: public wxImageHandler
|
||||
{
|
||||
public:
|
||||
inline wxJ2KHandler()
|
||||
{
|
||||
m_name = wxT("JPEG 2000 codestream file");
|
||||
m_extension = wxT("j2k");
|
||||
m_type = wxBITMAP_TYPE_J2K;
|
||||
m_mime = wxT("image/j2k");
|
||||
}
|
||||
|
||||
#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(wxJ2KHandler)
|
||||
};
|
||||
|
||||
#endif // wxUSE_LIBOPENJPEG
|
||||
|
||||
#endif // _WX_IMAGJ2K_H_
|
||||
|
286
OPJViewer/source/imagjp2.cpp
Normal file
286
OPJViewer/source/imagjp2.cpp
Normal file
@ -0,0 +1,286 @@
|
||||
/*
|
||||
* 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: imagjp2.cpp
|
||||
// Purpose: wxImage JPEG 2000 file format handler
|
||||
// Author: Giuseppe Baruffa - based on imagjpeg.cpp, Vaclav Slavik
|
||||
// RCS-ID: $Id: imagjp2.cpp,v 0.00 2007/02/08 23:59: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 "imagjp2.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
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// wxJP2Handler
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
IMPLEMENT_DYNAMIC_CLASS(wxJP2Handler,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
|
||||
|
||||
/* sample error callback expecting a FILE* client object */
|
||||
void jp2_error_callback(const char *msg, void *client_data) {
|
||||
char m_msg[MAX_MESSAGE_LEN];
|
||||
int message_len = strlen(msg) - 1;
|
||||
if (msg[message_len] != '\n')
|
||||
message_len = MAX_MESSAGE_LEN;
|
||||
sprintf(m_msg, "[ERROR] %.*s", message_len, msg);
|
||||
wxMutexGuiEnter();
|
||||
wxLogMessage(m_msg);
|
||||
wxMutexGuiLeave();
|
||||
}
|
||||
/* sample warning callback expecting a FILE* client object */
|
||||
void jp2_warning_callback(const char *msg, void *client_data) {
|
||||
char m_msg[MAX_MESSAGE_LEN];
|
||||
int message_len = strlen(msg) - 1;
|
||||
if (msg[message_len] != '\n')
|
||||
message_len = MAX_MESSAGE_LEN;
|
||||
sprintf(m_msg, "[WARNING] %.*s", message_len, msg);
|
||||
wxMutexGuiEnter();
|
||||
wxLogMessage(m_msg);
|
||||
wxMutexGuiLeave();
|
||||
}
|
||||
/* sample debug callback expecting no client object */
|
||||
void jp2_info_callback(const char *msg, void *client_data) {
|
||||
char m_msg[MAX_MESSAGE_LEN];
|
||||
int message_len = strlen(msg) - 1;
|
||||
if (msg[message_len] != '\n')
|
||||
message_len = MAX_MESSAGE_LEN;
|
||||
sprintf(m_msg, "[INFO] %.*s", message_len, msg);
|
||||
wxMutexGuiEnter();
|
||||
wxLogMessage(m_msg);
|
||||
wxMutexGuiLeave();
|
||||
}
|
||||
|
||||
// load the jp2 file format
|
||||
bool wxJP2Handler::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;
|
||||
FILE *fsrc = NULL;
|
||||
unsigned char *src = NULL;
|
||||
unsigned char *ptr;
|
||||
int file_length;
|
||||
|
||||
// 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 = jp2_error_callback;
|
||||
event_mgr.warning_handler = jp2_warning_callback;
|
||||
event_mgr.info_handler = jp2_info_callback;
|
||||
|
||||
/* set decoding parameters to default values */
|
||||
opj_set_default_decoder_parameters(¶meters);
|
||||
|
||||
/* prepare parameters */
|
||||
parameters.decod_format = JP2_CFMT;
|
||||
parameters.cod_format = BMP_DFMT;
|
||||
|
||||
/* get a decoder handle */
|
||||
dinfo = opj_create_decompress(CODEC_JP2);
|
||||
|
||||
/* find length of the stream */
|
||||
stream.SeekI(0, wxFromEnd);
|
||||
file_length = (int) stream.TellI();
|
||||
|
||||
/* get data */
|
||||
stream.SeekI(0, wxFromStart);
|
||||
src = (unsigned char *) malloc(file_length);
|
||||
stream.Read(src, file_length);
|
||||
|
||||
/* 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, file_length);
|
||||
|
||||
/* decode the stream and fill the image structure */
|
||||
opjimage = opj_decode(dinfo, cio);
|
||||
if (!opjimage) {
|
||||
wxMutexGuiEnter();
|
||||
wxLogError("JP2: failed to decode image!");
|
||||
wxMutexGuiLeave();
|
||||
opj_destroy_decompress(dinfo);
|
||||
opj_cio_close(cio);
|
||||
free(src);
|
||||
return false;
|
||||
}
|
||||
|
||||
// check image size
|
||||
if ((opjimage->numcomps != 1) && (opjimage->numcomps != 3)) {
|
||||
wxMutexGuiEnter();
|
||||
wxLogError("JP2: weird number of components");
|
||||
wxMutexGuiLeave();
|
||||
opj_destroy_decompress(dinfo);
|
||||
opj_cio_close(cio);
|
||||
free(src);
|
||||
return false;
|
||||
}
|
||||
|
||||
// prepare image size
|
||||
image->Create(opjimage->comps[0].w, opjimage->comps[0].h, true );
|
||||
|
||||
// access image raw data
|
||||
image->SetMask( false );
|
||||
ptr = image->GetData();
|
||||
|
||||
// RGB color picture
|
||||
if (opjimage->numcomps == 3) {
|
||||
int row, col;
|
||||
int *r = opjimage->comps[0].data;
|
||||
int *g = opjimage->comps[1].data;
|
||||
int *b = opjimage->comps[2].data;
|
||||
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 (opjimage->numcomps == 1) {
|
||||
int row, col;
|
||||
int *y = opjimage->comps[0].data;
|
||||
for (row = 0; row < opjimage->comps[0].h; row++) {
|
||||
for (col = 0; col < opjimage->comps[0].w; col++) {
|
||||
|
||||
*(ptr++) = *(y);
|
||||
*(ptr++) = *(y);
|
||||
*(ptr++) = *(y++);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
wxMutexGuiEnter();
|
||||
wxLogMessage(wxT("JP2: image loaded."));
|
||||
wxMutexGuiLeave();
|
||||
|
||||
/* close openjpeg structs */
|
||||
opj_destroy_decompress(dinfo);
|
||||
opj_cio_close(cio);
|
||||
opj_image_destroy(opjimage);
|
||||
free(src);
|
||||
|
||||
if (!image->Ok())
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
// save the jp2 file format
|
||||
bool wxJP2Handler::SaveFile( wxImage *image, wxOutputStream& stream, bool verbose )
|
||||
{
|
||||
wxLogError(wxT("JP2: Couldn't save image -> not implemented."));
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef __VISUALC__
|
||||
#pragma warning(default:4611)
|
||||
#endif /* VC++ */
|
||||
|
||||
// recognize the JPEG 2000 starting box
|
||||
bool wxJP2Handler::DoCanRead( wxInputStream& stream )
|
||||
{
|
||||
unsigned char hdr[23];
|
||||
|
||||
if ( !stream.Read(hdr, WXSIZEOF(hdr)) )
|
||||
return false;
|
||||
|
||||
return (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);
|
||||
}
|
||||
|
||||
#endif // wxUSE_STREAMS
|
||||
|
||||
#endif // wxUSE_LIBOPENJPEG
|
75
OPJViewer/source/imagjp2.h
Normal file
75
OPJViewer/source/imagjp2.h
Normal file
@ -0,0 +1,75 @@
|
||||
/*
|
||||
* 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: imagjp2.h
|
||||
// Purpose: wxImage JPEG 2000 file format handler
|
||||
// Author: G. Baruffa - based on imagjpeg.h, Vaclav Slavik
|
||||
// RCS-ID: $Id: imagjp2.h,v 0.0 2007/02/08 23:45:00 VZ Exp $
|
||||
// Copyright: (c) Giuseppe Baruffa
|
||||
// Licence: wxWindows licence
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _WX_IMAGJP2_H_
|
||||
#define _WX_IMAGJP2_H_
|
||||
|
||||
#include "wx/defs.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// wxJP2Handler
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#if wxUSE_LIBOPENJPEG
|
||||
|
||||
#include "wx/image.h"
|
||||
|
||||
#define wxBITMAP_TYPE_JP2 48
|
||||
|
||||
class WXDLLEXPORT wxJP2Handler: public wxImageHandler
|
||||
{
|
||||
public:
|
||||
inline wxJP2Handler()
|
||||
{
|
||||
m_name = wxT("JPEG 2000 file format");
|
||||
m_extension = wxT("jp2");
|
||||
m_type = wxBITMAP_TYPE_JP2;
|
||||
m_mime = wxT("image/jp2");
|
||||
}
|
||||
|
||||
#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(wxJP2Handler)
|
||||
};
|
||||
|
||||
#endif // wxUSE_LIBOPENJPEG
|
||||
|
||||
#endif // _WX_IMAGJP2_H_
|
||||
|
785
OPJViewer/source/imagmj2.cpp
Normal file
785
OPJViewer/source/imagmj2.cpp
Normal file
@ -0,0 +1,785 @@
|
||||
/*
|
||||
* 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: imagmj2.cpp
|
||||
// Purpose: wxImage Motion JPEG 2000 file format handler
|
||||
// Author: Giuseppe Baruffa - based on imagjpeg.cpp, Vaclav Slavik
|
||||
// RCS-ID: $Id: imagmj2.cpp,v 0.00 2007/02/18 23:59: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 "imagmj2.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
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// wxMJ2Handler
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
IMPLEMENT_DYNAMIC_CLASS(wxMJ2Handler,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
|
||||
|
||||
/* sample error callback expecting a FILE* client object */
|
||||
void mj2_error_callback(const char *msg, void *client_data) {
|
||||
char m_msg[MAX_MESSAGE_LEN];
|
||||
int message_len = strlen(msg) - 1;
|
||||
if (msg[message_len] != '\n')
|
||||
message_len = MAX_MESSAGE_LEN;
|
||||
sprintf(m_msg, "[ERROR] %.*s", message_len, msg);
|
||||
wxMutexGuiEnter();
|
||||
wxLogMessage(m_msg);
|
||||
wxMutexGuiLeave();
|
||||
}
|
||||
/* sample warning callback expecting a FILE* client object */
|
||||
void mj2_warning_callback(const char *msg, void *client_data) {
|
||||
char m_msg[MAX_MESSAGE_LEN];
|
||||
int message_len = strlen(msg) - 1;
|
||||
if (msg[message_len] != '\n')
|
||||
message_len = MAX_MESSAGE_LEN;
|
||||
sprintf(m_msg, "[WARNING] %.*s", message_len, msg);
|
||||
wxMutexGuiEnter();
|
||||
wxLogMessage(m_msg);
|
||||
wxMutexGuiLeave();
|
||||
}
|
||||
/* sample debug callback expecting no client object */
|
||||
void mj2_info_callback(const char *msg, void *client_data) {
|
||||
char m_msg[MAX_MESSAGE_LEN];
|
||||
int message_len = strlen(msg) - 1;
|
||||
if (msg[message_len] != '\n')
|
||||
message_len = MAX_MESSAGE_LEN;
|
||||
sprintf(m_msg, "[INFO] %.*s", message_len, msg);
|
||||
wxMutexGuiEnter();
|
||||
wxLogMessage(m_msg);
|
||||
wxMutexGuiLeave();
|
||||
}
|
||||
|
||||
/* 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)
|
||||
#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)
|
||||
|
||||
/* 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 J2FILENUM 4
|
||||
typedef enum {
|
||||
|
||||
JP2_FILE,
|
||||
J2K_FILE,
|
||||
MJ2_FILE,
|
||||
UNK_FILE
|
||||
|
||||
} my_j2filetype;
|
||||
|
||||
/* enumeration for the box types */
|
||||
#define J2BOXNUM 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
|
||||
|
||||
} my_j2boxtype;
|
||||
|
||||
/* 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 MINF_SIGN "minf"
|
||||
#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 my_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 */
|
||||
my_j2boxtype ins; /* contained in box... */
|
||||
|
||||
};
|
||||
|
||||
/* the possible boxes */
|
||||
struct my_boxdef j2box[] =
|
||||
{
|
||||
/* 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
|
||||
my_box_handler_function(my_j2boxtype boxtype, wxInputStream& stream, unsigned long int filepoint, unsigned long int filelimit, int level,
|
||||
char *scansign, unsigned long int *scanpoint);
|
||||
|
||||
/* internal mini-search for a box signature */
|
||||
int
|
||||
my_jpeg2000parse(wxInputStream& stream, unsigned long int filepoint, unsigned long int filelimit, 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;
|
||||
__int64 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];
|
||||
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)) {
|
||||
(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, j2box[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 */
|
||||
my_box_handler_function((my_j2boxtype) box_type, stream, (LBox == 1) ? (filepoint + 16) : (filepoint + 8), filepoint + box_length, level,
|
||||
scansign, scanpoint);
|
||||
|
||||
/* if it's a superbox go inside it */
|
||||
if (j2box[box_type].sbox)
|
||||
my_jpeg2000parse(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
|
||||
searchfirstjp2c(wxInputStream& stream, unsigned long int fsize)
|
||||
{
|
||||
char scansign[] = "jp2c";
|
||||
unsigned long int scanpoint = 0L;
|
||||
|
||||
wxLogMessage("MJ2: searching jp2c box... ");
|
||||
|
||||
/* do the parsing */
|
||||
if (my_jpeg2000parse(stream, 0, fsize, 0, scansign, &scanpoint) < 0)
|
||||
wxLogMessage("MJ2: Unrecoverable error during file parsing: stopping");
|
||||
|
||||
if (strcmp(scansign, " "))
|
||||
wxLogMessage("MJ2: not found");
|
||||
else {
|
||||
|
||||
wxLogMessage(wxString::Format("MJ2: found at byte %d", scanpoint));
|
||||
|
||||
};
|
||||
|
||||
|
||||
return (scanpoint);
|
||||
}
|
||||
|
||||
// search the jp2h box in the file
|
||||
unsigned long int
|
||||
searchjpegheaderbox(wxInputStream& stream, unsigned long int fsize)
|
||||
{
|
||||
char scansign[] = "jp2h";
|
||||
unsigned long int scanpoint = 0L;
|
||||
|
||||
wxLogMessage("MJ2: searching jp2h box... ");
|
||||
|
||||
/* do the parsing */
|
||||
if (my_jpeg2000parse(stream, 0, fsize, 0, scansign, &scanpoint) < 0)
|
||||
wxLogMessage("Unrecoverable error during file parsing: stopping");
|
||||
|
||||
if (strcmp(scansign, " "))
|
||||
wxLogMessage("MJ2: not found");
|
||||
else
|
||||
wxLogMessage(wxString::Format("MJ2: found at byte %d", scanpoint));
|
||||
|
||||
return (scanpoint);
|
||||
}
|
||||
|
||||
/* handling functions */
|
||||
#define ITEM_PER_ROW 10
|
||||
|
||||
/* Box handler function */
|
||||
int
|
||||
my_box_handler_function(my_j2boxtype 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):
|
||||
my_jpeg2000parse(stream, filepoint + 8, filelimit, level, scansign, scanpoint);
|
||||
break;
|
||||
|
||||
/* MJP2 Sample Description box */
|
||||
case (MJP2_BOX):
|
||||
my_jpeg2000parse(stream, filepoint + 78, filelimit, level, scansign, scanpoint);
|
||||
break;
|
||||
|
||||
/* not yet implemented */
|
||||
default:
|
||||
break;
|
||||
|
||||
};
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
// the jP and ftyp parts of the header
|
||||
#define my_jPheadSIZE 32
|
||||
unsigned char my_jPhead[my_jPheadSIZE] = {
|
||||
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 mj2 file format
|
||||
bool wxMJ2Handler::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;
|
||||
FILE *fsrc = NULL;
|
||||
unsigned char *src = NULL;
|
||||
unsigned char *ptr;
|
||||
int file_length, jp2c_point, jp2h_point;
|
||||
unsigned long int jp2hboxlen, jp2cboxlen;
|
||||
|
||||
// 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 = mj2_error_callback;
|
||||
event_mgr.warning_handler = mj2_warning_callback;
|
||||
event_mgr.info_handler = mj2_info_callback;
|
||||
|
||||
/* set decoding parameters to default values */
|
||||
opj_set_default_decoder_parameters(¶meters);
|
||||
|
||||
/* prepare parameters */
|
||||
parameters.decod_format = JP2_CFMT;
|
||||
parameters.cod_format = BMP_DFMT;
|
||||
|
||||
/* get a decoder handle */
|
||||
dinfo = opj_create_decompress(CODEC_JP2);
|
||||
|
||||
/* find length of the stream */
|
||||
stream.SeekI(0, wxFromEnd);
|
||||
file_length = (int) stream.TellI();
|
||||
|
||||
/* search for the first codestream box and the movie header box */
|
||||
jp2c_point = searchfirstjp2c(stream, file_length);
|
||||
jp2h_point = searchjpegheaderbox(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(my_jPheadSIZE + jp2hboxlen + jp2cboxlen);
|
||||
|
||||
// copy the jP and ftyp
|
||||
memcpy(src, my_jPhead, my_jPheadSIZE);
|
||||
|
||||
// copy the jp2h
|
||||
stream.SeekI(jp2h_point, wxFromStart);
|
||||
stream.Read(&src[my_jPheadSIZE], jp2hboxlen);
|
||||
|
||||
// copy the jp2c
|
||||
stream.SeekI(jp2c_point, wxFromStart);
|
||||
stream.Read(&src[my_jPheadSIZE + jp2hboxlen], jp2cboxlen);
|
||||
|
||||
/* 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, my_jPheadSIZE + jp2hboxlen + jp2cboxlen);
|
||||
|
||||
/* decode the stream and fill the image structure */
|
||||
opjimage = opj_decode(dinfo, cio);
|
||||
if (!opjimage) {
|
||||
wxMutexGuiEnter();
|
||||
wxLogError("MJ2: failed to decode image!");
|
||||
wxMutexGuiLeave();
|
||||
opj_destroy_decompress(dinfo);
|
||||
opj_cio_close(cio);
|
||||
free(src);
|
||||
return false;
|
||||
}
|
||||
|
||||
// check image size
|
||||
if ((opjimage->numcomps != 1) && (opjimage->numcomps != 3)) {
|
||||
wxMutexGuiEnter();
|
||||
wxLogError("MJ2: weird number of components");
|
||||
wxMutexGuiLeave();
|
||||
opj_destroy_decompress(dinfo);
|
||||
opj_cio_close(cio);
|
||||
free(src);
|
||||
return false;
|
||||
}
|
||||
|
||||
// prepare image size
|
||||
image->Create(opjimage->comps[0].w, opjimage->comps[0].h, true );
|
||||
|
||||
// access image raw data
|
||||
image->SetMask( false );
|
||||
ptr = image->GetData();
|
||||
|
||||
// RGB color picture
|
||||
// does not handle comps. subsampling,
|
||||
// so simply render the first component
|
||||
if (opjimage->numcomps == 3) {
|
||||
int row, col;
|
||||
int *r = opjimage->comps[0].data;
|
||||
/*
|
||||
int *g = opjimage->comps[1].data;
|
||||
int *b = opjimage->comps[2].data;
|
||||
*/
|
||||
for (row = 0; row < opjimage->comps[0].h; row++) {
|
||||
for (col = 0; col < opjimage->comps[0].w; col++) {
|
||||
|
||||
/*
|
||||
*(ptr++) = *(r++);
|
||||
*(ptr++) = *(g++);
|
||||
*(ptr++) = *(b++);
|
||||
*/
|
||||
*(ptr++) = *(r);
|
||||
*(ptr++) = *(r);
|
||||
*(ptr++) = *(r++);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// B/W picture
|
||||
if (opjimage->numcomps == 1) {
|
||||
int row, col;
|
||||
int *y = opjimage->comps[0].data;
|
||||
for (row = 0; row < opjimage->comps[0].h; row++) {
|
||||
for (col = 0; col < opjimage->comps[0].w; col++) {
|
||||
|
||||
*(ptr++) = *(y);
|
||||
*(ptr++) = *(y);
|
||||
*(ptr++) = *(y++);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
wxMutexGuiEnter();
|
||||
wxLogMessage(wxT("MJ2: image loaded."));
|
||||
wxMutexGuiLeave();
|
||||
|
||||
/* close openjpeg structs */
|
||||
opj_destroy_decompress(dinfo);
|
||||
opj_cio_close(cio);
|
||||
opj_image_destroy(opjimage);
|
||||
free(src);
|
||||
|
||||
if (!image->Ok())
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
// save the mj2 file format
|
||||
bool wxMJ2Handler::SaveFile( wxImage *image, wxOutputStream& stream, bool verbose )
|
||||
{
|
||||
wxLogError(wxT("MJ2: Couldn't save movie -> not implemented."));
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef __VISUALC__
|
||||
#pragma warning(default:4611)
|
||||
#endif /* VC++ */
|
||||
|
||||
// recognize the Motion JPEG 2000 starting box
|
||||
bool wxMJ2Handler::DoCanRead( wxInputStream& stream )
|
||||
{
|
||||
unsigned char hdr[24];
|
||||
|
||||
if ( !stream.Read(hdr, WXSIZEOF(hdr)) )
|
||||
return false;
|
||||
|
||||
return (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);
|
||||
}
|
||||
|
||||
#endif // wxUSE_STREAMS
|
||||
|
||||
#endif // wxUSE_LIBOPENJPEG
|
75
OPJViewer/source/imagmj2.h
Normal file
75
OPJViewer/source/imagmj2.h
Normal file
@ -0,0 +1,75 @@
|
||||
/*
|
||||
* 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: imagmj2.h
|
||||
// Purpose: wxImage Motion JPEG 2000 file format handler
|
||||
// Author: G. Baruffa - based on imagjpeg.h, Vaclav Slavik
|
||||
// RCS-ID: $Id: imagmj2.h,v 0.0 2007/02/18 23:45:00 VZ Exp $
|
||||
// Copyright: (c) Giuseppe Baruffa
|
||||
// Licence: wxWindows licence
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _WX_IMAGMJ2_H_
|
||||
#define _WX_IMAGMJ2_H_
|
||||
|
||||
#include "wx/defs.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// wxMJ2Handler
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#if wxUSE_LIBOPENJPEG
|
||||
|
||||
#include "wx/image.h"
|
||||
|
||||
#define wxBITMAP_TYPE_MJ2 49
|
||||
|
||||
class WXDLLEXPORT wxMJ2Handler: public wxImageHandler
|
||||
{
|
||||
public:
|
||||
inline wxMJ2Handler()
|
||||
{
|
||||
m_name = wxT("Motion JPEG 2000 file format");
|
||||
m_extension = wxT("mj2");
|
||||
m_type = wxBITMAP_TYPE_MJ2;
|
||||
m_mime = wxT("image/mj2");
|
||||
}
|
||||
|
||||
#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(wxMJ2Handler)
|
||||
};
|
||||
|
||||
#endif // wxUSE_LIBOPENJPEG
|
||||
|
||||
#endif // _WX_IMAGMJ2_H_
|
||||
|
337
OPJViewer/source/wxj2kparser.cpp
Normal file
337
OPJViewer/source/wxj2kparser.cpp
Normal file
@ -0,0 +1,337 @@
|
||||
/*
|
||||
* 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 */
|
||||
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,
|
||||
CME_VAL = 0xFF64,
|
||||
#ifndef USEOLDJPWL
|
||||
EPB_VAL = 0xFF66,
|
||||
ESD_VAL = 0xFF67,
|
||||
EPC_VAL = 0xFF68,
|
||||
RED_VAL = 0xFF69
|
||||
#else
|
||||
EPB_VAL = 0xFF96,
|
||||
ESD_VAL = 0xFF98,
|
||||
EPC_VAL = 0xFF97,
|
||||
RED_VAL = 0xFF99
|
||||
#endif
|
||||
};
|
||||
|
||||
// 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,
|
||||
CME_VAL,
|
||||
EPB_VAL, ESD_VAL, EPC_VAL, RED_VAL
|
||||
};
|
||||
|
||||
// Marker names
|
||||
char *marker_name[] = {
|
||||
"SOC", "SOT", "SOD", "EOC",
|
||||
"SIZ",
|
||||
"COD", "COC", "RGN", "QCD", "QCC", "POD",
|
||||
"TLM", "PLM", "PLT", "PPM", "PPT",
|
||||
"SOP", "EPH",
|
||||
"CME",
|
||||
"EPB", "ESD", "EPC", "RED"
|
||||
};
|
||||
|
||||
// Marker descriptions
|
||||
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",
|
||||
"Error Protection Block", "Error Sensitivity Descriptor", "Error Protection Capability",
|
||||
"Residual Errors Descriptor"
|
||||
};
|
||||
|
||||
void OPJParseThread::ParseJ2KFile(wxFile *m_file, wxFileOffset offset, wxFileOffset length, wxTreeItemId parentid)
|
||||
{
|
||||
// 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);
|
||||
|
||||
//WriteText(wxString::Format(wxT("from to %d"), length));
|
||||
|
||||
// navigate the file
|
||||
int m, inside_sod = 0, nmarks = 0, maxmarks = 10000, done = 0;
|
||||
unsigned char onebyte[1];
|
||||
unsigned char twobytes[2];
|
||||
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;
|
||||
|
||||
// read da marka
|
||||
if (m_file->Read(twobytes, 2) != 2)
|
||||
break;
|
||||
currmark = (((unsigned short int) twobytes[0]) << 8) + (unsigned short int) twobytes[1];
|
||||
|
||||
// Markers cycle
|
||||
for (m = 0; m < 23; m++) {
|
||||
|
||||
// check the marker
|
||||
if (currmark == marker_val[m]) {
|
||||
|
||||
if (currmark == SOD_VAL) {
|
||||
|
||||
// we enter SOD
|
||||
currlen = 0;
|
||||
inside_sod = 1;
|
||||
|
||||
} else if ((currmark == SOC_VAL) || (currmark == EOC_VAL) || (currmark == EPH_VAL))
|
||||
|
||||
currlen = 0;
|
||||
|
||||
else {
|
||||
|
||||
// read length
|
||||
if (m_file->Read(twobytes, 2) != 2)
|
||||
break;
|
||||
currlen = (((unsigned short int) twobytes[0]) << 8) + (unsigned short int) twobytes[1];
|
||||
|
||||
}
|
||||
|
||||
// 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 */
|
||||
|
||||
if (inside_sod && (currmark == SOT_VAL) && (lastPsot == 0))
|
||||
inside_sod = 0; /* random data coincident with SOT, but last SOT was the last one */
|
||||
|
||||
if (inside_sod && (currmark == SOT_VAL))
|
||||
inside_sod = 0; /* new tile part */
|
||||
|
||||
// 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(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) {
|
||||
|
||||
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"))
|
||||
);
|
||||
}
|
||||
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 (m_file->Read(fourbytes, 4) != 4)
|
||||
break;
|
||||
unsigned long int ysiz = STREAM_TO_UINT32(fourbytes, 0);
|
||||
|
||||
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(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"))
|
||||
);
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
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;
|
||||
};
|
||||
break;
|
||||
|
||||
case CME_VAL:
|
||||
{
|
||||
#define showlen 25
|
||||
unsigned char comment[showlen];
|
||||
|
||||
m_file->Seek(2, wxFromCurrent);
|
||||
if (m_file->Read(comment, showlen) != showlen)
|
||||
break;
|
||||
|
||||
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"))
|
||||
);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
// increment number of markers
|
||||
nmarks++;
|
||||
if (nmarks >= maxmarks)
|
||||
break;
|
||||
|
||||
// increment offset
|
||||
if (currmark == SOD_VAL)
|
||||
offset += lastPsot - (offset - lastsotpos);
|
||||
else
|
||||
offset += (2 + currlen);
|
||||
|
||||
m_file->Seek(offset, wxFromStart);
|
||||
done = 1;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (done)
|
||||
continue;
|
||||
else {
|
||||
offset++;
|
||||
m_file->Seek(offset, wxFromStart);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
851
OPJViewer/source/wxjp2parser.cpp
Normal file
851
OPJViewer/source/wxjp2parser.cpp
Normal file
@ -0,0 +1,851 @@
|
||||
/*
|
||||
* 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 J2BOXNUM 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
|
||||
|
||||
} j2boxtype;
|
||||
|
||||
/* 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 */
|
||||
j2boxtype ins; /* contained in box... */
|
||||
|
||||
};
|
||||
|
||||
/* the possible boxes */
|
||||
struct boxdef j2box[];
|
||||
|
||||
/* 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)
|
||||
#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))
|
||||
|
||||
/* 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 ((j2boxtype) 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,
|
||||
wxString::Format(wxT("Brand/Minor version: %.4s/%d"), BR, 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::Format(wxT("%.4s"), CL),
|
||||
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 (%s)"), METH, methdescr),
|
||||
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 (%s)"), EnumCS, enumcsdescr),
|
||||
m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,
|
||||
new OPJMarkerData(wxT("INFO"))
|
||||
);
|
||||
|
||||
if (METH != 1)
|
||||
currid = m_tree->AppendItem(parentid,
|
||||
wxString::Format("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 {
|
||||
unsigned __int64 creation_time, modification_time, duration;
|
||||
unsigned long int timescale;
|
||||
fileid->Read(&creation_time, sizeof(unsigned __int64));
|
||||
creation_time = BYTE_SWAP8(creation_time);
|
||||
fileid->Read(&modification_time, sizeof(unsigned __int64));
|
||||
modification_time = BYTE_SWAP8(modification_time);
|
||||
fileid->Read(×cale, sizeof(unsigned long int));
|
||||
timescale = BYTE_SWAP4(timescale);
|
||||
fileid->Read(&duration, sizeof(unsigned __int64));
|
||||
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;
|
||||
|
||||
|
||||
|
||||
/* 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;
|
||||
|
||||
|
||||
/* not yet implemented */
|
||||
default:
|
||||
break;
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* 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 MINF_SIGN "minf"
|
||||
#define STBL_SIGN "stbl"
|
||||
#define STSD_SIGN "stsd"
|
||||
#define MJP2_SIGN "mjp2"
|
||||
#define MDAT_SIGN "mdat"
|
||||
#define ANY_SIGN ""
|
||||
#define UNK_SIGN ""
|
||||
|
||||
/* the possible boxes */
|
||||
struct boxdef j2box[] =
|
||||
{
|
||||
/* 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}
|
||||
|
||||
};
|
||||
|
||||
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;
|
||||
__int64 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, j2box[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: %s (0x%04X)"), box_num, TBox,
|
||||
((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(j2box[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 (j2box[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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user