summaryrefslogtreecommitdiff
path: root/OPJViewer/source/wxj2kparser.cpp
diff options
context:
space:
mode:
authorFrancois-Olivier Devaux <fodevaux@users.noreply.github.com>2007-02-22 17:05:58 +0000
committerFrancois-Olivier Devaux <fodevaux@users.noreply.github.com>2007-02-22 17:05:58 +0000
commite841b13166218ba152595a7c0adf5b70c4e5558d (patch)
treefbb9de20f67208fe6cdaf24a218368cae5e2e1e2 /OPJViewer/source/wxj2kparser.cpp
parent7cb2194c8e31acc867e6f674ca16c67764f09ba0 (diff)
Added the OPJViewer Module (/OPJViewer), developed by Giuseppe Baruffa of the University of Perugia
Diffstat (limited to 'OPJViewer/source/wxj2kparser.cpp')
-rw-r--r--OPJViewer/source/wxj2kparser.cpp337
1 files changed, 337 insertions, 0 deletions
diff --git a/OPJViewer/source/wxj2kparser.cpp b/OPJViewer/source/wxj2kparser.cpp
new file mode 100644
index 00000000..7e189d7b
--- /dev/null
+++ b/OPJViewer/source/wxj2kparser.cpp
@@ -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);
+ }
+ }
+
+}