diff --git a/ChangeLog b/ChangeLog index ae8d6622..40f5798f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -5,6 +5,9 @@ What's New for OpenJPEG ! : changed + : added +March 30, 2007 +* [GB] OPJViewer should now work under Linux, at least with not big j2k files. Tested under Suse 10.1 64 bit. + March 29, 2007 * [Parvatha] Enable accepting file names with `-´ symbol .Modification getopt.c * [Parvatha] Rsiz profile name generation to be STD_RSIZ for profiles which are not DCI compliant.Modification in image_to_j2k.c diff --git a/OPJViewer/Makefile b/OPJViewer/Makefile new file mode 100644 index 00000000..1224f421 --- /dev/null +++ b/OPJViewer/Makefile @@ -0,0 +1,41 @@ +# Makefile for the main JPWL OpenJPEG codecs: JPWL_ j2k_to_image and JPWL_image_to_j2k + +# General configuration variables: +CC = $(shell wx-config-2.8 --cxx) +AR = ar + +CFLAGS = -DUSE_JPWL -DwxUSE_LIBOPENJPEG -DwxUSE_GUI=1 -DOPJ_STATIC -DOPJ_HTMLABOUT $(shell wx-config-2.8 --cxxflags) # -g -p -pg -DUSE_JPWL + +OPJV_SRCS = source/imagj2k.cpp source/imagmj2.cpp source/wxj2kparser.cpp source/imagjp2.cpp source/OPJViewer.cpp source/wxjp2parser.cpp + +MODULES = $(OPJV_SRCS:.cpp=.o) + +all: opjviewer lib + +.cpp.o: + $(CC) $(CFLAGS) -c $< -o $@ + +lib: + cd ../jpwl; make + +opjviewer: $(OPJV_SRCS) lib + $(CC) $(CFLAGS) -I .. $(OPJV_SRCS) -o OPJViewer -L ../jpwl -lopenjpeg_JPWL -lm -lstdc++ -ltiff $(shell wx-config-2.8 --libs) + + +clean: + rm -f OPJViewer *.o *.a + cd ../libopenjpeg; rm -f *.o + + + + +#.cpp.o : +# $(CXX) -g -c `wx-config-2.8 --cxxflags` -I ../.. -D wxUSE_LIBOPENJPEG -D wxHACK_BOOLEAN -o $@ $< + +#all: $(PROGRAM) + +#$(PROGRAM): $(OBJECTS) +# $(CXX) -o $(PROGRAM) $(OBJECTS) -lopenjpeg -L ../.. `wx-config-2.8 --libs` + +#clean: +# rm -f *.o $(PROGRAM) diff --git a/OPJViewer/source/OPJViewer.cpp b/OPJViewer/source/OPJViewer.cpp index d796fbb2..1dcd026e 100644 --- a/OPJViewer/source/OPJViewer.cpp +++ b/OPJViewer/source/OPJViewer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, Digital Signal Processing Laboratory, Università degli studi di Perugia (UPG), Italy + * 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 @@ -351,7 +351,7 @@ OPJFrame::OPJFrame(wxWindow *parent, const wxWindowID id, const wxString& title, // create the text control of the logger m_textCtrl = new wxTextCtrl(m_bookCtrlbottom, wxID_ANY, wxT(""), wxDefaultPosition, wxDefaultSize, - wxTE_MULTILINE | wxSUNKEN_BORDER | wxTE_READONLY + wxTE_MULTILINE | wxSUNKEN_BORDER | wxTE_READONLY ); m_textCtrl->SetValue(_T("Logging window\n")); @@ -361,7 +361,7 @@ OPJFrame::OPJFrame(wxWindow *parent, const wxWindowID id, const wxString& title, // create the text control of the browser m_textCtrlbrowse = new wxTextCtrl(m_bookCtrlbottom, wxID_ANY, wxT(""), wxDefaultPosition, wxDefaultSize, - wxTE_MULTILINE | wxSUNKEN_BORDER | wxTE_READONLY | wxTE_RICH + wxTE_MULTILINE | wxSUNKEN_BORDER | wxTE_READONLY | wxTE_RICH ); wxFont *browsefont = new wxFont(wxNORMAL_FONT->GetPointSize(), wxFONTFAMILY_TELETYPE, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL); @@ -430,7 +430,8 @@ void OPJFrame::OnNotebook(wxNotebookEvent& event) m_bookCtrl->GetPageText(sel).ToLong(&childnum); - m_childhash[childnum]->Activate(); + if (m_childhash[childnum]) + m_childhash[childnum]->Activate(); //wxLogMessage(wxT("Selection changed (now %d --> %d)"), childnum, m_childhash[childnum]->m_winnumber); @@ -458,9 +459,9 @@ void OPJFrame::OnSetsDeco(wxCommandEvent& event) wxGetApp().m_enablejpwl = dialog.m_enablejpwlCheck->GetValue(); wxGetApp().m_expcomps = dialog.m_expcompsCtrl->GetValue(); wxGetApp().m_maxtiles = dialog.m_maxtilesCtrl->GetValue(); -#endif // USE_JPWL - - }; +#endif // USE_JPWL + + }; } void OPJFrame::OnQuit(wxCommandEvent& WXUNUSED(event)) @@ -744,6 +745,8 @@ OPJCanvas::OPJCanvas(wxFileName fname, wxWindow *parent, const wxPoint& pos, con m_fname = fname; m_childframe = (OPJChildFrame *) parent; + // 100% zoom + m_zooml = 100; OPJDecoThread *dthread = CreateDecoThread(); @@ -753,7 +756,8 @@ OPJCanvas::OPJCanvas(wxFileName fname, wxWindow *parent, const wxPoint& pos, con wxLogMessage(wxT("New deco thread started.")); // 100% zoom - m_zooml = 100; + //m_zooml = 100; + } OPJDecoThread *OPJCanvas::CreateDecoThread(void) @@ -1113,7 +1117,7 @@ void OPJParseThread::LoadFile(wxFileName fname) else //m_tree->SetItemText(rootid, wxString::Format(wxT("%s (%d B)"), fname.GetFullName(), m_file.Length())); m_tree->SetItemText(rootid, fname.GetFullName()); - + // close the file m_file.Close(); @@ -1347,7 +1351,7 @@ void OPJMarkerTree::OnSelChanged(wxTreeEvent& event) fp->Seek(data->m_start, wxFromStart); // read a bunch - int max_read = wxMin(WXSIZEOF(buffer), data->m_length - data->m_start + 1); + int max_read = wxMin(wxFileOffset(WXSIZEOF(buffer)), data->m_length - data->m_start + 1); fp->Read(buffer, max_read); // write the file data between start and stop @@ -1795,12 +1799,16 @@ void OPJDecoThread::WriteText(const wxString& text) // before doing any GUI calls we must ensure that this thread is the only // one doing it! +#ifndef __WXGTK__ wxMutexGuiEnter(); +#endif // __WXGTK__ msg << text; m_canvas->WriteText(msg); +#ifndef __WXGTK__ wxMutexGuiLeave(); +#endif // __WXGTK__ } void OPJDecoThread::OnExit() @@ -1827,18 +1835,23 @@ void *OPJDecoThread::Entry() wxString text; srand(GetId()); - int m_countnum = rand() % 9; + //int m_countnum = rand() % 9; //text.Printf(wxT("Deco thread 0x%lx started (priority = %u, time = %d)."), // GetId(), GetPriority(), m_countnum); text.Printf(wxT("Deco thread %d started"), m_canvas->m_childframe->m_winnumber); + + + + WriteText(text); wxBitmap bitmap(100, 100); - wxImage image = bitmap.ConvertToImage(); + wxImage image(100, 100, true); //= bitmap.ConvertToImage(); image.Destroy(); WriteText(m_canvas->m_fname.GetFullPath()); + // set handler properties wxJ2KHandler *j2kkkhandler = (wxJ2KHandler *) wxImage::FindHandler( wxBITMAP_TYPE_J2K); j2kkkhandler->m_reducefactor = wxGetApp().m_reducefactor; @@ -1888,7 +1901,9 @@ void *OPJDecoThread::Entry() zooml = wxMin(100, wxMin(wzooml, hzooml)); // fit to width +#ifndef __WXGTK__ m_canvas->m_childframe->m_frame->Rescale(zooml, m_canvas->m_childframe); +#endif // __WXGTK__ //m_canvas->m_image = m_canvas->m_image100; //m_canvas->Refresh(); @@ -1897,8 +1912,8 @@ void *OPJDecoThread::Entry() //text.Printf(wxT("Deco thread 0x%lx finished."), GetId()); text.Printf(wxT("Deco thread %d finished"), m_canvas->m_childframe->m_winnumber); WriteText(text); - return NULL; + } ///////////////////////////////////////////////////////////////////// @@ -1920,12 +1935,16 @@ void OPJParseThread::WriteText(const wxString& text) // before doing any GUI calls we must ensure that this thread is the only // one doing it! +#ifndef __WXGTK__ wxMutexGuiEnter(); +#endif // __WXGTK msg << text; m_tree->WriteText(msg); +#ifndef __WXGTK__ wxMutexGuiLeave(); +#endif // __WXGTK } void OPJParseThread::OnExit() @@ -1948,6 +1967,8 @@ void OPJParseThread::OnExit() void *OPJParseThread::Entry() { + printf("Entering\n\n"); + wxString text; srand(GetId()); @@ -1955,7 +1976,12 @@ void *OPJParseThread::Entry() text.Printf(wxT("Parse thread 0x%lx started (priority = %u, time = %d)."), GetId(), GetPriority(), m_countnum); WriteText(text); - // wxLogMessage(text); -- test wxLog thread safeness + LoadFile(m_tree->m_fname); + text.Printf(wxT("Parse thread 0x%lx finished."), GetId()); + WriteText(text); + + + //wxLogMessage(wxT("Entering\n")); //test wxLog thread safeness //wxBusyCursor wait; //wxBusyInfo wait(wxT("Decoding image ...")); @@ -1974,13 +2000,10 @@ void *OPJParseThread::Entry() wxThread::Sleep(10); }*/ - - LoadFile(m_tree->m_fname); - - text.Printf(wxT("Parse thread 0x%lx finished."), GetId()); - WriteText(text); // wxLogMessage(text); -- test wxLog thread safeness + printf("Exiting\n\n"); + return NULL; } diff --git a/OPJViewer/source/OPJViewer.h b/OPJViewer/source/OPJViewer.h index 2dde2f73..deb3e8f0 100644 --- a/OPJViewer/source/OPJViewer.h +++ b/OPJViewer/source/OPJViewer.h @@ -209,7 +209,15 @@ class OPJCanvas: public wxScrolledWindow virtual void OnDraw(wxDC& dc); void OnEvent(wxMouseEvent& event); - void WriteText(const wxString& text) { wxMutexGuiEnter(); wxLogMessage(text); wxMutexGuiLeave();} + void WriteText(const wxString& text) { +#ifndef __WXGTK__ + wxMutexGuiEnter(); +#endif //__WXGTK__ + wxLogMessage(text); +#ifndef __WXGTK__ + wxMutexGuiLeave(); +#endif //__WXGTK__ + } OPJDecoThread *CreateDecoThread(void); OPJChildFrame *m_childframe; diff --git a/OPJViewer/source/imagj2k.cpp b/OPJViewer/source/imagj2k.cpp index 4a7ed492..65f9a42b 100644 --- a/OPJViewer/source/imagj2k.cpp +++ b/OPJViewer/source/imagj2k.cpp @@ -85,27 +85,27 @@ void j2k_error_callback(const char *msg, void *client_data) { int message_len = strlen(msg) - 1; if (msg[message_len] != '\n') message_len = MAX_MESSAGE_LEN; - wxMutexGuiEnter(); + /*wxMutexGuiEnter(); wxLogMessage(wxT("[ERROR] %.*s"), message_len, msg); - wxMutexGuiLeave(); + wxMutexGuiLeave();*/ } /* sample warning callback expecting a FILE* client object */ void j2k_warning_callback(const char *msg, void *client_data) { int message_len = strlen(msg) - 1; if (msg[message_len] != '\n') message_len = MAX_MESSAGE_LEN; - wxMutexGuiEnter(); + /*wxMutexGuiEnter(); wxLogMessage(wxT("[WARNING] %.*s"), message_len, msg); - wxMutexGuiLeave(); + wxMutexGuiLeave();*/ } /* sample debug callback expecting no client object */ void j2k_info_callback(const char *msg, void *client_data) { int message_len = strlen(msg) - 1; if (msg[message_len] != '\n') message_len = MAX_MESSAGE_LEN; - wxMutexGuiEnter(); + /*wxMutexGuiEnter(); wxLogMessage(wxT("[INFO] %.*s"), message_len, msg); - wxMutexGuiLeave(); + wxMutexGuiLeave();*/ } // load the j2k codestream @@ -126,6 +126,7 @@ bool wxJ2KHandler::LoadFile(wxImage *image, wxInputStream& stream, bool verbose, 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; diff --git a/OPJViewer/source/imagjp2.cpp b/OPJViewer/source/imagjp2.cpp index b1a23bde..849c6e45 100644 --- a/OPJViewer/source/imagjp2.cpp +++ b/OPJViewer/source/imagjp2.cpp @@ -112,6 +112,7 @@ void jp2_info_callback(const char *msg, void *client_data) { wxMutexGuiLeave(); } + // load the jp2 file format bool wxJP2Handler::LoadFile(wxImage *image, wxInputStream& stream, bool verbose, int index) { diff --git a/OPJViewer/source/wxj2kparser.cpp b/OPJViewer/source/wxj2kparser.cpp index 8401d251..02d8b4a5 100644 --- a/OPJViewer/source/wxj2kparser.cpp +++ b/OPJViewer/source/wxj2kparser.cpp @@ -251,7 +251,9 @@ void OPJParseThread::ParseJ2KFile(wxFile *m_file, wxFileOffset offset, wxFileOff // append the marker wxTreeItemId currid = m_tree->AppendItem(parentid, - wxString::Format(wxT("%03d: %s (0x%04X)"), nmarks, marker_name[m], marker_val[m]), + wxString::Format(wxT("%03d: "), nmarks) + + wxString::FromAscii(marker_name[m]) + + wxString::Format(wxT(" (0x%04X)"), marker_val[m]), image, imageSel, new OPJMarkerData(wxT("MARK"), m_tree->m_fname.GetFullPath(), offset, offset + currlen + 1) ); @@ -262,7 +264,7 @@ void OPJParseThread::ParseJ2KFile(wxFile *m_file, wxFileOffset offset, wxFileOff // marker name wxTreeItemId subcurrid1 = m_tree->AppendItem(currid, - wxT("*** ") + wxString::Format(wxT("%s"), marker_descr[m]) + wxT(" ***"), + wxT("*** ") + wxString::FromAscii(marker_descr[m]) + wxT(" ***"), image, imageSel, new OPJMarkerData(wxT("INFO")) ); @@ -555,7 +557,7 @@ void OPJParseThread::ParseJ2KFile(wxFile *m_file, wxFileOffset offset, wxFileOff case SIZ_VAL: { int c; - + if (m_file->Read(twobytes, 2) != 2) break; unsigned short int rsiz = STREAM_TO_UINT16(twobytes, 0); @@ -1179,7 +1181,8 @@ void OPJParseThread::ParseJ2KFile(wxFile *m_file, wxFileOffset offset, wxFileOff case COM_VAL: { #define showlen 25 - unsigned char comment[showlen]; + char comment[showlen]; + wxString comments; if (m_file->Read(twobytes, 2) != 2) break; @@ -1202,9 +1205,11 @@ void OPJParseThread::ParseJ2KFile(wxFile *m_file, wxFileOffset offset, wxFileOff if (m_file->Read(comment, showlen) != showlen) break; + comments = wxString::FromAscii(comment).Truncate(wxMin(showlen, currlen - 4)); + if ((currlen - 4) > showlen) + comments << wxT("..."); subcurrid3 = m_tree->AppendItem(currid, - wxString::Format(wxT("%.*s%s"), wxMin(showlen, currlen - 4), comment, - (((currlen - 4) > showlen) ? "..." : "")), + comments, image, imageSel, new OPJMarkerData(wxT("INFO")) ); diff --git a/OPJViewer/source/wxjp2parser.cpp b/OPJViewer/source/wxjp2parser.cpp index 9291f9aa..4832870f 100644 --- a/OPJViewer/source/wxjp2parser.cpp +++ b/OPJViewer/source/wxjp2parser.cpp @@ -398,7 +398,9 @@ int OPJParseThread::box_handler_function(int boxtype, wxFile *fileid, wxFileOffs // add info wxTreeItemId currid = m_tree->AppendItem(parentid, - wxString::Format(wxT("Brand/Minor version: %.4s/%d"), BR, MinV), + wxT("Brand/Minor version: ") + + wxString::FromAscii(BR).Truncate(4) + + wxString::Format(wxT("/%d"), MinV), m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1, new OPJMarkerData(wxT("INFO")) ); @@ -412,7 +414,7 @@ int OPJParseThread::box_handler_function(int boxtype, wxFile *fileid, wxFileOffs for (i = 0; i < numCL; i++) { fileid->Read(CL, sizeof(char) * 4); m_tree->AppendItem(currid, - wxString::Format(wxT("%.4s"), CL), + wxString::FromAscii(CL).Truncate(4), m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1, new OPJMarkerData(wxT("INFO")) ); @@ -511,7 +513,9 @@ int OPJParseThread::box_handler_function(int boxtype, wxFile *fileid, wxFileOffs // add info wxTreeItemId currid = m_tree->AppendItem(parentid, - wxString::Format(wxT("Specification method: %d (%s)"), METH, methdescr), + wxString::Format(wxT("Specification method: %d ("), METH) + + wxString::FromAscii(methdescr) + + wxT(")"), m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1, new OPJMarkerData(wxT("INFO")) ); @@ -530,7 +534,9 @@ int OPJParseThread::box_handler_function(int boxtype, wxFile *fileid, wxFileOffs if (METH != 2) currid = m_tree->AppendItem(parentid, - wxString::Format(wxT("Enumerated colourspace: %d (%s)"), EnumCS, enumcsdescr), + wxString::Format(wxT("Enumerated colourspace: %d ("), EnumCS) + + wxString::FromAscii(enumcsdescr) + + wxT(")"), m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1, new OPJMarkerData(wxT("INFO")) ); @@ -758,7 +764,9 @@ int OPJParseThread::box_handler_function(int boxtype, wxFile *fileid, wxFileOffs opcolor[2] = BYTE_SWAP2(opcolor[2]); wxTreeItemId currid = m_tree->AppendItem(parentid, - wxString::Format(wxT("Composition mode: %d (%s)"), graphicsmode, graphicsdescr), + wxString::Format(wxT("Composition mode: %d (")) + + wxString::FromAscii(graphicsdescr) + + wxT(")"), m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1, new OPJMarkerData(wxT("INFO"), m_tree->m_fname.GetFullPath(), filepoint, filelimit) ); @@ -922,7 +930,9 @@ int OPJParseThread::jpeg2000parse(wxFile *fileid, wxFileOffset filepoint, wxFile image = m_tree->TreeCtrlIcon_Folder; imageSel = image + 1; wxTreeItemId currid = m_tree->AppendItem(parentid, - wxString::Format(wxT("%03d: %s (0x%04X)"), box_num, TBox, + wxString::Format(wxT("%03d: "), box_num) + + wxString::FromAscii(TBox) + + wxString::Format(wxT(" (0x%04X)"), ((unsigned long int) TBox[3]) + ((unsigned long int) TBox[2] << 8) + ((unsigned long int) TBox[1] << 16) + ((unsigned long int) TBox[0] << 24) ), @@ -936,7 +946,7 @@ int OPJParseThread::jpeg2000parse(wxFile *fileid, wxFileOffset filepoint, wxFile // box name wxTreeItemId subcurrid1 = m_tree->AppendItem(currid, - wxT("*** ") + wxString::Format(wxT("%s"), j22box[box_type].name) + wxT(" ***"), + wxT("*** ") + wxString::FromAscii(j22box[box_type].name) + wxT(" ***"), image, imageSel, new OPJMarkerData(wxT("INFO")) );