From 3f36196dfdd740417d5dfd7d7d313dd179d4a304 Mon Sep 17 00:00:00 2001 From: Giuseppe Baruffa Date: Tue, 27 Mar 2007 12:48:17 +0000 Subject: Improved parsing in OPJViewer, as well some aesthetic modifications; support for image rendering with bit depths lower than 8 bits; can display an arbitrary frame of an MJ2 file (only in B/W, though); can reload a file; better image resizing capabilities --- OPJViewer/source/wxj2kparser.cpp | 1420 +++++++++++++++++++++++++++++++++----- 1 file changed, 1265 insertions(+), 155 deletions(-) (limited to 'OPJViewer/source/wxj2kparser.cpp') diff --git a/OPJViewer/source/wxj2kparser.cpp b/OPJViewer/source/wxj2kparser.cpp index 30289567..98f9fe7c 100644 --- a/OPJViewer/source/wxj2kparser.cpp +++ b/OPJViewer/source/wxj2kparser.cpp @@ -40,6 +40,7 @@ /* Markers values */ +#define J2KMARK_NUM 24 enum { SOC_VAL = 0xFF4F, SOT_VAL = 0xFF90, @@ -59,18 +60,20 @@ enum { PPT_VAL = 0xFF61, SOP_VAL = 0xFF91, EPH_VAL = 0xFF92, - CME_VAL = 0xFF64, -#ifndef USEOLDJPWL - EPB_VAL = 0xFF66, + COM_VAL = 0xFF64 +#ifdef USE_JPWL + , EPB_VAL = 0xFF66, ESD_VAL = 0xFF67, EPC_VAL = 0xFF68, RED_VAL = 0xFF69 -#else - EPB_VAL = 0xFF96, + /*, EPB_VAL = 0xFF96, ESD_VAL = 0xFF98, EPC_VAL = 0xFF97, - RED_VAL = 0xFF99 -#endif + RED_VAL = 0xFF99*/ +#endif // USE_JPWL +#ifdef USE_JPSEC + , SEC_VAL = 0xFF65 +#endif // USE_JPSEC }; // All the markers in one vector @@ -80,8 +83,13 @@ unsigned short int marker_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 + COM_VAL +#ifdef USE_JPWL + , EPB_VAL, ESD_VAL, EPC_VAL, RED_VAL +#endif // USE_JPWL +#ifdef USE_JPSEC + , SEC_VAL +#endif // USE_JPSEC }; // Marker names @@ -91,8 +99,13 @@ char *marker_name[] = { "COD", "COC", "RGN", "QCD", "QCC", "POD", "TLM", "PLM", "PLT", "PPM", "PPT", "SOP", "EPH", - "CME", - "EPB", "ESD", "EPC", "RED" + "COM" +#ifdef USE_JPWL + , "EPB", "ESD", "EPC", "RED" +#endif // USE_JPWL +#ifdef USE_JPSEC + , "SEC" +#endif // USE_JPSEC }; // Marker descriptions @@ -104,13 +117,20 @@ char *marker_descr[] = { "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", + "Comment and extension" +#ifdef USE_JPWL + , "Error Protection Block", "Error Sensitivity Descriptor", "Error Protection Capability", "Residual Errors Descriptor" +#endif // USE_JPWL +#ifdef USE_JPSEC + , "Main security marker" +#endif // USE_JPSEC }; void OPJParseThread::ParseJ2KFile(wxFile *m_file, wxFileOffset offset, wxFileOffset length, wxTreeItemId parentid) { + unsigned short int csiz = 0; + // check if the file is opened if (m_file->IsOpened()) WriteText(wxT("File OK")); @@ -120,218 +140,1308 @@ void OPJParseThread::ParseJ2KFile(wxFile *m_file, wxFileOffset offset, wxFileOff // position at the beginning m_file->Seek(offset, wxFromStart); - //WriteText(wxString::Format(wxT("from to %d"), length)); - // navigate the file - int m, inside_sod = 0, nmarks = 0, maxmarks = 10000, done = 0; + int m, inside_sod = 0, inside_sop = 0; + int nmarks = 0, maxmarks = 10000; unsigned char onebyte[1]; - unsigned char twobytes[2]; + unsigned char twobytes[2], firstbyte, secondbyte; unsigned char fourbytes[4]; unsigned short int currmark; unsigned short int currlen; int lastPsot = 0, lastsotpos = 0; WriteText(wxT("Start search...")); - while ((offset < length) && (!m_file->Eof())) { - done = 0; +// advancing macro +#define OPJ_ADVANCE(A) {offset += A; if (offset < length) m_file->Seek(offset, wxFromStart); else return;} - // read da marka - if (m_file->Read(twobytes, 2) != 2) + // begin search + while ((offset < length) && (!m_file->Eof())) { + + // read one byte + if (m_file->Read(&firstbyte, 1) != 1) break; - currmark = (((unsigned short int) twobytes[0]) << 8) + (unsigned short int) twobytes[1]; - // Markers cycle - for (m = 0; m < 23; m++) { + // look for 0xFF + if (firstbyte == 0xFF) { - // check the marker - if (currmark == marker_val[m]) { + // it is a possible marker + if (m_file->Read(&secondbyte, 1) != 1) + break; + else + currmark = (((unsigned short int) firstbyte) << 8) + (unsigned short int) secondbyte; - if (currmark == SOD_VAL) { + } else { - // we enter SOD - currlen = 0; - inside_sod = 1; + // nope, advance by one and search again + OPJ_ADVANCE(1); + continue; + } + + // search the marker + for (m = 0; m < J2KMARK_NUM; m++) { + if (currmark == marker_val[m]) + break; + } - } else if ((currmark == SOC_VAL) || (currmark == EOC_VAL) || (currmark == EPH_VAL)) - - currlen = 0; + // marker not found + if (m == J2KMARK_NUM) { + // nope, advance by one and search again + OPJ_ADVANCE(1); + continue; + } - else { + // if we are inside SOD, only some markers are allowed + if (inside_sod) { - // read length - if (m_file->Read(twobytes, 2) != 2) - break; - currlen = (((unsigned short int) twobytes[0]) << 8) + (unsigned short int) twobytes[1]; + // we are inside SOP + if (inside_sop) { + + } + // randomly marker coincident data + if ((currmark != SOT_VAL) && + (currmark != EOC_VAL) /*&& + (currmark != SOP_VAL) && + (currmark != EPH_VAL)*/) { + OPJ_ADVANCE(1); + continue; + } + + // possible SOT? + if ((currmark == SOT_VAL)) { + // too early SOT + if (offset < (lastsotpos + lastPsot)) { + OPJ_ADVANCE(1); + continue; } + // we were not in the last tile + /*if (lastPsot != 0) { + OPJ_ADVANCE(1); + break; + }*/ + } + } - // inside SOD, only some markers are allowed - if (inside_sod && (currmark != SOD_VAL) && (currmark != SOT_VAL) - && (currmark != EOC_VAL) && (currmark != SOP_VAL) && (currmark != EPH_VAL)) - break; /*randomly marker coincident data */ + // beyond this point, the marker MUST BE real - if (inside_sod && (currmark == SOT_VAL) && (lastPsot == 0)) - inside_sod = 0; /* random data coincident with SOT, but last SOT was the last one */ + // length of current marker segment + if ((currmark == SOD_VAL) || + (currmark == SOC_VAL) || + (currmark == EOC_VAL) || + (currmark == EPH_VAL)) - if (inside_sod && (currmark == SOT_VAL)) - inside_sod = 0; /* new tile part */ + // zero length markers + currlen = 0; - // here we pass to AppendItem() normal and selected item images (we - // suppose that selected image follows the normal one in the enum) - int image, imageSel; - image = m_tree->TreeCtrlIcon_Folder; - imageSel = image + 1; + else { + + // read length field + if (m_file->Read(twobytes, 2) != 2) + break; + + currlen = (((unsigned short int) twobytes[0]) << 8) + (unsigned short int) twobytes[1]; + } + + // here we pass to AppendItem() normal and selected item images (we + // suppose that selected image follows the normal one in the enum) + int image, imageSel; + image = m_tree->TreeCtrlIcon_Folder; + imageSel = image + 1; + + // append the marker + wxTreeItemId currid = m_tree->AppendItem(parentid, + wxString::Format(wxT("%03d: %s (0x%04X)"), nmarks, marker_name[m], marker_val[m]), + image, imageSel, + new OPJMarkerData(wxT("MARK"), m_tree->m_fname.GetFullPath(), offset, offset + currlen + 1) + ); + + // append some info + image = m_tree->TreeCtrlIcon_File; + imageSel = image + 1; + + // marker name + wxTreeItemId subcurrid1 = m_tree->AppendItem(currid, + wxT("*** ") + wxString::Format(wxT("%s"), marker_descr[m]) + wxT(" ***"), + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + m_tree->SetItemFont(subcurrid1, *wxITALIC_FONT); + + // position and length + wxTreeItemId subcurrid2 = m_tree->AppendItem(currid, + wxLongLong(offset).ToString() + wxT(" > ") + wxLongLong(offset + currlen + 1).ToString() + + wxT(", ") + wxString::Format(wxT("%d + 2 (%d)"), currlen, currlen + 2), + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + // give additional info on markers + switch (currmark) { + + ///////// + // SOP // + ///////// + case SOP_VAL: + { + // read packet number + if (m_file->Read(twobytes, 2) != 2) + break; + int packnum = STREAM_TO_UINT16(twobytes, 0); + + image = m_tree->TreeCtrlIcon_File; + imageSel = image + 1; + + wxTreeItemId subcurrid3 = m_tree->AppendItem(currid, + wxString::Format(wxT("Pack. no. %d"), packnum), + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + inside_sop = 1; + }; + break; + + ///////// + // RED // + ///////// + case RED_VAL: + { + if (m_file->Read(onebyte, 1) != 1) + break; + unsigned char pred = onebyte[0]; + + image = m_tree->TreeCtrlIcon_File; + imageSel = image + 1; + + wxString address[] = { + wxT("Packet addressing"), + wxT("Byte-range addressing"), + wxT("Packet-range addressing"), + wxT("Reserved") + }; + + wxTreeItemId subcurrid = m_tree->AppendItem(currid, + address[(pred & 0xC0) >> 6], + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + subcurrid = m_tree->AppendItem(currid, + wxString::Format(wxT("%d bytes range"), (((pred & 0x02) >> 1) + 1) * 2), + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + subcurrid = m_tree->AppendItem(currid, + pred & 0x01 ? wxT("Errors/erasures in codestream") : wxT("Error free codestream"), + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + subcurrid = m_tree->AppendItem(currid, + wxString::Format(wxT("Residual corruption level: %d"), (pred & 0x38) >> 3), + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + } + break; + + ///////// + // ESD // + ///////// + case ESD_VAL: + { + unsigned short int cesd; + if (csiz < 257) { + if (m_file->Read(onebyte, 1) != 1) + break; + cesd = onebyte[0]; + } else { + if (m_file->Read(twobytes, 2) != 2) + break; + cesd = STREAM_TO_UINT16(twobytes, 0); + } + + if (m_file->Read(onebyte, 1) != 1) + break; + unsigned char pesd = onebyte[0]; + + image = m_tree->TreeCtrlIcon_File; + imageSel = image + 1; + + wxTreeItemId subcurrid = m_tree->AppendItem(currid, + pesd & 0x01 ? wxT("Comp. average") : wxString::Format(wxT("Comp. no. %d"), cesd), + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + wxString meth[] = { + wxT("Relative error sensitivity"), + wxT("MSE"), + wxT("MSE reduction"), + wxT("PSNR"), + wxT("PSNR increase"), + wxT("MAXERR (absolute peak error)"), + wxT("TSE (total squared error)"), + wxT("Reserved") + }; + + subcurrid = m_tree->AppendItem(currid, + meth[(pesd & 0x38) >> 3], + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + wxString address[] = { + wxT("Packet addressing"), + wxT("Byte-range addressing"), + wxT("Packet-range addressing"), + wxT("Reserved") + }; + + subcurrid = m_tree->AppendItem(currid, + address[(pesd & 0xC0) >> 6], + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + subcurrid = m_tree->AppendItem(currid, + wxString::Format(wxT("%d bytes/value, %d bytes range"), ((pesd & 0x04) >> 2) + 1, (((pesd & 0x02) >> 1) + 1) * 2), + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + } + break; + + ///////// + // EPC // + ///////// + case EPC_VAL: + { + if (m_file->Read(twobytes, 2) != 2) + break; + unsigned short int pcrc = STREAM_TO_UINT16(twobytes, 0); + + if (m_file->Read(fourbytes, 4) != 4) + break; + unsigned long int dl = STREAM_TO_UINT32(fourbytes, 0); + + if (m_file->Read(onebyte, 1) != 1) + break; + unsigned char pepc = onebyte[0]; + + image = m_tree->TreeCtrlIcon_File; + imageSel = image + 1; + + wxTreeItemId subcurrid = m_tree->AppendItem(currid, + wxString::Format(wxT("CRC-16 = 0x%x"), pcrc), + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); - // append the marker - wxTreeItemId currid = m_tree->AppendItem(parentid, - wxString::Format(wxT("%03d: %s (0x%04X)"), nmarks, marker_name[m], marker_val[m]), + subcurrid = m_tree->AppendItem(currid, + wxString::Format(wxT("Tot. length = %d"), dl), + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + subcurrid = m_tree->AppendItem(currid, + wxString::Format(wxT("%s%s%s%s"), + pepc & 0x10 ? wxT("ESD, ") : wxT(""), + pepc & 0x20 ? wxT("RED, ") : wxT(""), + pepc & 0x40 ? wxT("EPB, ") : wxT(""), + pepc & 0x80 ? wxT("Info") : wxT("") + ), + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + } + break; + + ///////// + // EPB // + ///////// + case EPB_VAL: + { + if (m_file->Read(onebyte, 1) != 1) + break; + unsigned char depb = onebyte[0]; + + if (m_file->Read(fourbytes, 4) != 4) + break; + unsigned long int ldpepb = STREAM_TO_UINT32(fourbytes, 0); + + if (m_file->Read(fourbytes, 4) != 4) + break; + unsigned long int pepb = STREAM_TO_UINT32(fourbytes, 0); + + image = m_tree->TreeCtrlIcon_File; + imageSel = image + 1; + + wxTreeItemId subcurrid = m_tree->AppendItem(currid, + wxString::Format(wxT("No. %d, %slatest, %spacked"), + depb & 0x3F, + depb & 0x40 ? wxT("") : wxT("not "), + depb & 0x80 ? wxT("") : wxT("un")), + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + subcurrid = m_tree->AppendItem(currid, + wxString::Format(wxT("%d bytes protected"), ldpepb), + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + if (pepb == 0x00000000) + + subcurrid = m_tree->AppendItem(currid, + wxT("Predefined codes"), image, imageSel, - new OPJMarkerData(wxT("MARK"), m_tree->m_fname.GetFullPath(), offset, offset + currlen + 1) + new OPJMarkerData(wxT("INFO")) ); - // append some info - image = m_tree->TreeCtrlIcon_File; - imageSel = image + 1; + else if ((pepb >= 0x10000000) && (pepb <= 0x1FFFFFFF)) { - // marker name - wxTreeItemId subcurrid1 = m_tree->AppendItem(currid, - wxT("*** ") + wxString::Format(wxT("%s"), marker_descr[m]) + wxT(" ***"), + wxString text = wxT("CRC code"); + if (pepb == 0x10000000) + text << wxT(", CCITT (X25) 16 bits"); + else if (pepb == 0x10000001) + text << wxT(", Ethernet 32 bits"); + else + text << wxT(", JPWL RA"); + subcurrid = m_tree->AppendItem(currid, + text, image, imageSel, new OPJMarkerData(wxT("INFO")) ); - m_tree->SetItemFont(subcurrid1, *wxITALIC_FONT); - // position and length - wxTreeItemId subcurrid2 = m_tree->AppendItem(currid, - wxLongLong(offset).ToString() + wxT(" > ") + wxLongLong(offset + currlen + 1).ToString() + - wxT(", ") + wxString::Format(wxT("%d + 2 (%d)"), currlen, currlen + 2), + } else if ((pepb >= 0x20000000) && (pepb <= 0x2FFFFFFF)) { + + wxString text; + subcurrid = m_tree->AppendItem(currid, + wxString::Format(wxT("RS code, RS(%d, %d)"), + (pepb & 0x0000FF00) >> 8, + (pepb & 0x000000FF)), image, imageSel, new OPJMarkerData(wxT("INFO")) ); - // give additional info on markers - switch (currmark) { - - case SOP_VAL: - { - // read packet number - if (m_file->Read(twobytes, 2) != 2) - break; - int packnum = STREAM_TO_UINT16(twobytes, 0);; - wxTreeItemId subcurrid3 = m_tree->AppendItem(currid, - wxString::Format(wxT("Pack. no. %d"), packnum), - image, imageSel, - new OPJMarkerData(wxT("INFO")) - ); - } + } else if ((pepb >= 0x30000000) && (pepb <= 0x3FFFFFFE)) + + subcurrid = m_tree->AppendItem(currid, + wxT("JPWL RA"), + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + else if (pepb == 0xFFFFFFFF) + + subcurrid = m_tree->AppendItem(currid, + wxT("No method"), + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + } + break; + + ///////// + // SIZ // + ///////// + case SIZ_VAL: + { + if (m_file->Read(twobytes, 2) != 2) + break; + unsigned short int rsiz = STREAM_TO_UINT16(twobytes, 0); + + if (m_file->Read(fourbytes, 4) != 4) + break; + unsigned long int xsiz = STREAM_TO_UINT32(fourbytes, 0); + + if (m_file->Read(fourbytes, 4) != 4) + break; + unsigned long int ysiz = STREAM_TO_UINT32(fourbytes, 0); + + if (m_file->Read(fourbytes, 4) != 4) + break; + unsigned long int xosiz = STREAM_TO_UINT32(fourbytes, 0); + + if (m_file->Read(fourbytes, 4) != 4) + break; + unsigned long int yosiz = STREAM_TO_UINT32(fourbytes, 0); + + if (m_file->Read(fourbytes, 4) != 4) + break; + unsigned long int xtsiz = STREAM_TO_UINT32(fourbytes, 0); + this->m_tree->m_childframe->m_twidth = xtsiz; + + if (m_file->Read(fourbytes, 4) != 4) + break; + unsigned long int ytsiz = STREAM_TO_UINT32(fourbytes, 0); + this->m_tree->m_childframe->m_theight = ytsiz; + + if (m_file->Read(fourbytes, 4) != 4) + break; + unsigned long int xtosiz = STREAM_TO_UINT32(fourbytes, 0); + this->m_tree->m_childframe->m_tx = xtosiz; + + if (m_file->Read(fourbytes, 4) != 4) + break; + unsigned long int ytosiz = STREAM_TO_UINT32(fourbytes, 0); + this->m_tree->m_childframe->m_ty = ytosiz; + + if (m_file->Read(twobytes, 2) != 2) + break; + csiz = STREAM_TO_UINT16(twobytes, 0); + + bool equaldepth = true, equalsize = true; + unsigned char *ssiz = new unsigned char(csiz); + unsigned char *xrsiz = new unsigned char(csiz); + unsigned char *yrsiz = new unsigned char(csiz); + + for (int c = 0; c < csiz; c++) { + + if (m_file->Read(&ssiz[c], 1) != 1) break; - case SIZ_VAL: - { - m_file->Seek(2, wxFromCurrent); - if (m_file->Read(fourbytes, 4) != 4) - break; - unsigned long int xsiz = STREAM_TO_UINT32(fourbytes, 0); + if (c > 0) + equaldepth = equaldepth && (ssiz[c] == ssiz[c - 1]); - if (m_file->Read(fourbytes, 4) != 4) - break; - unsigned long int ysiz = STREAM_TO_UINT32(fourbytes, 0); + if (m_file->Read(&xrsiz[c], 1) != 1) + break; - m_file->Seek(24, wxFromCurrent); - if (m_file->Read(twobytes, 2) != 2) - break; - unsigned short int csiz = STREAM_TO_UINT16(twobytes, 0); + if (m_file->Read(&yrsiz[c], 1) != 1) + break; + + if (c > 0) + equalsize = equalsize && (xrsiz[c] == xrsiz[c - 1]) && (yrsiz[c] == yrsiz[c - 1]) ; + + } + + if (equaldepth && equalsize) + wxTreeItemId subcurrid3 = m_tree->AppendItem(currid, + wxString::Format(wxT("I: %dx%d (%d, %d), %d c., %d%s bpp"), + xsiz, ysiz, + xosiz, yosiz, + csiz, ((ssiz[0] & 0x7F) + 1), + (ssiz[0] & 0x80) ? wxT("s") : wxT("u")), + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + else + wxTreeItemId subcurrid3 = m_tree->AppendItem(currid, + wxString::Format(wxT("I: %dx%d (%d, %d), %d c."), + xsiz, ysiz, + xosiz, yosiz, + csiz), + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + wxTreeItemId subcurrid3 = m_tree->AppendItem(currid, + wxString::Format(wxT("T: %dx%d (%d, %d)"), + xtsiz, ytsiz, + xtosiz, ytosiz), + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + image = m_tree->TreeCtrlIcon_Folder; + imageSel = image + 1; + + wxTreeItemId subcurrid4 = m_tree->AppendItem(currid, + wxT("Components"), + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + image = m_tree->TreeCtrlIcon_File; + imageSel = image + 1; + + for (c = 0; c < csiz; c++) { + + wxTreeItemId subcurrid5 = m_tree->AppendItem(subcurrid4, + wxString::Format(wxT("#%d: %dx%d, %d%s bpp"), + c, + xsiz/xrsiz[c], ysiz/yrsiz[c], + ((ssiz[c] & 0x7F) + 1), + (ssiz[c] & 0x80) ? wxT("s") : wxT("u")), + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + } + + }; + break; + + ///////// + // SOT // + ///////// + case SOT_VAL: + { + if (m_file->Read(twobytes, 2) != 2) + break; + unsigned short int isot = STREAM_TO_UINT16(twobytes, 0); + + if (m_file->Read(fourbytes, 4) != 4) + break; + unsigned long int psot = STREAM_TO_UINT32(fourbytes, 0); + + if (m_file->Read(onebyte, 1) != 1) + break; + unsigned char tpsot = onebyte[0]; + + if (m_file->Read(onebyte, 1) != 1) + break; + unsigned char tnsot = onebyte[0]; + + wxTreeItemId subcurrid3 = m_tree->AppendItem(currid, + wxString::Format(wxT("tile %d, psot = %d, part %d of %d"), isot, psot, tpsot, tnsot), + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + lastPsot = psot; + lastsotpos = offset; + inside_sod = 0; + }; + break; + + ///////// + // COC // + ///////// + case COC_VAL: + { + unsigned short int ccoc; + if (csiz < 257) { + if (m_file->Read(onebyte, 1) != 1) + break; + ccoc = onebyte[0]; + } else { + if (m_file->Read(twobytes, 2) != 2) + break; + ccoc = STREAM_TO_UINT16(twobytes, 0); + } + + if (m_file->Read(onebyte, 1) != 1) + break; + unsigned char scoc = onebyte[0]; + + wxTreeItemId subcurrid = m_tree->AppendItem(currid, + wxString::Format(wxT("Comp. no. %d"), ccoc), + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + wxString text; + if (scoc & 0x01) + text << wxT("Partitioned entropy coder"); + else + text << wxT("Unpartitioned entropy coder"); + + subcurrid = m_tree->AppendItem(currid, + text, + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + if (m_file->Read(onebyte, 1) != 1) + break; + unsigned char decomplevs = onebyte[0]; + + if (m_file->Read(onebyte, 1) != 1) + break; + unsigned char cbswidth = onebyte[0]; + + if (m_file->Read(onebyte, 1) != 1) + break; + unsigned char cbsheight = onebyte[0]; + + if (m_file->Read(onebyte, 1) != 1) + break; + unsigned char cbstyle = onebyte[0]; + + if (m_file->Read(onebyte, 1) != 1) + break; + unsigned char transform = onebyte[0]; + + subcurrid = m_tree->AppendItem(currid, + wxString::Format(wxT("%d levels (%d resolutions)"), decomplevs, decomplevs + 1), + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + if (transform & 0x01) + text = wxT("5-3 reversible wavelet"); + else + text = wxT("9-7 irreversible wavelet"); + subcurrid = m_tree->AppendItem(currid, + text, + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + subcurrid = m_tree->AppendItem(currid, + wxString::Format(wxT("Code-blocks: %dx%d"), 1 << ((cbswidth & 0x0F) + 2), 1 << ((cbsheight & 0x0F) + 2)), + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + image = m_tree->TreeCtrlIcon_Folder; + imageSel = image + 1; + wxTreeItemId subcurrid3 = m_tree->AppendItem(currid, + wxT("Coding styles"), + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + image = m_tree->TreeCtrlIcon_File; + imageSel = image + 1; + + if (cbstyle & 0x01) + text = wxT("Selective arithmetic coding bypass"); + else + text = wxT("No selective arithmetic coding bypass"); + wxTreeItemId subcurrid4 = m_tree->AppendItem(subcurrid3, + text, + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + if (cbstyle & 0x02) + text = wxT("Reset context probabilities on coding pass boundaries"); + else + text = wxT("No reset of context probabilities on coding pass boundaries"); + subcurrid4 = m_tree->AppendItem(subcurrid3, + text, + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + if (cbstyle & 0x04) + text = wxT("Termination on each coding passs"); + else + text = wxT("No termination on each coding pass"); + subcurrid4 = m_tree->AppendItem(subcurrid3, + text, + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + if (cbstyle & 0x08) + text = wxT("Vertically stripe causal context"); + else + text = wxT("No vertically stripe causal context"); + subcurrid4 = m_tree->AppendItem(subcurrid3, + text, + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + if (cbstyle & 0x10) + text = wxT("Predictable termination"); + else + text = wxT("No predictable termination"); + subcurrid4 = m_tree->AppendItem(subcurrid3, + text, + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + if (cbstyle & 0x20) + text = wxT("Segmentation symbols are used"); + else + text = wxT("No segmentation symbols are used"); + subcurrid4 = m_tree->AppendItem(subcurrid3, + text, + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + } + break; + + ///////// + // COD // + ///////// + case COD_VAL: + { + if (m_file->Read(onebyte, 1) != 1) + break; + unsigned char scod = onebyte[0]; + + wxString text; + + if (scod & 0x01) + text << wxT("Partitioned entropy coder"); + else + text << wxT("Unpartitioned entropy coder"); + + wxTreeItemId subcurrid3 = m_tree->AppendItem(currid, + text, + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + text = wxT(""); + if (scod & 0x02) + text << wxT("Possible SOPs"); + else + text << wxT("No SOPs"); + + if (scod & 0x04) + text << wxT(", possible EPHs"); + else + text << wxT(", no EPHs"); + + subcurrid3 = m_tree->AppendItem(currid, + text, + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + if (m_file->Read(onebyte, 1) != 1) + break; + unsigned char progord = onebyte[0]; + + if (m_file->Read(twobytes, 2) != 2) + break; + unsigned short int numlayers = STREAM_TO_UINT16(twobytes, 0); + + if (m_file->Read(onebyte, 1) != 1) + break; + unsigned char mctransform = onebyte[0]; + + if (m_file->Read(onebyte, 1) != 1) + break; + unsigned char decomplevs = onebyte[0]; + + if (m_file->Read(onebyte, 1) != 1) + break; + unsigned char cbswidth = onebyte[0]; + + if (m_file->Read(onebyte, 1) != 1) + break; + unsigned char cbsheight = onebyte[0]; + + if (m_file->Read(onebyte, 1) != 1) + break; + unsigned char cbstyle = onebyte[0]; + + if (m_file->Read(onebyte, 1) != 1) + break; + unsigned char transform = onebyte[0]; + + subcurrid3 = m_tree->AppendItem(currid, + wxString::Format(wxT("%d levels (%d resolutions)"), decomplevs, decomplevs + 1), + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + text = wxT(""); + switch (progord) { + case (0): + text << wxT("LRCP"); + break; + case (1): + text << wxT("RLCP"); + break; + case (2): + text << wxT("LRCP"); + break; + case (3): + text << wxT("RPCL"); + break; + case (4): + text << wxT("CPRL"); + break; + default: + text << wxT("unknown progression"); + break; + } + text << wxString::Format(wxT(", %d layers"), numlayers); + if (transform & 0x01) + text << wxT(", 5-3 rev."); + else + text << wxT(", 9-7 irr."); + subcurrid3 = m_tree->AppendItem(currid, + text, + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + subcurrid3 = m_tree->AppendItem(currid, + wxString::Format(wxT("Code-blocks: %dx%d"), 1 << ((cbswidth & 0x0F) + 2), 1 << ((cbsheight & 0x0F) + 2)), + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + switch (mctransform) { + case (0): + { + text = wxT("No MCT"); + } + break; + case (1): + { + text = wxT("Reversible MCT on 0, 1, 2"); + } + break; + case (2): + { + text = wxT("Irreversible MCT on 0, 1, 2"); + } + break; + default: + { + text = wxT("Unknown"); + } + break; + }; + subcurrid3 = m_tree->AppendItem(currid, + text, + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + + image = m_tree->TreeCtrlIcon_Folder; + imageSel = image + 1; + + subcurrid3 = m_tree->AppendItem(currid, + wxT("Coding styles"), + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + image = m_tree->TreeCtrlIcon_File; + imageSel = image + 1; + + if (cbstyle & 0x01) + text = wxT("Selective arithmetic coding bypass"); + else + text = wxT("No selective arithmetic coding bypass"); + wxTreeItemId subcurrid4 = m_tree->AppendItem(subcurrid3, + text, + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + if (cbstyle & 0x02) + text = wxT("Reset context probabilities on coding pass boundaries"); + else + text = wxT("No reset of context probabilities on coding pass boundaries"); + subcurrid4 = m_tree->AppendItem(subcurrid3, + text, + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + if (cbstyle & 0x04) + text = wxT("Termination on each coding passs"); + else + text = wxT("No termination on each coding pass"); + subcurrid4 = m_tree->AppendItem(subcurrid3, + text, + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + if (cbstyle & 0x08) + text = wxT("Vertically stripe causal context"); + else + text = wxT("No vertically stripe causal context"); + subcurrid4 = m_tree->AppendItem(subcurrid3, + text, + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + if (cbstyle & 0x10) + text = wxT("Predictable termination"); + else + text = wxT("No predictable termination"); + subcurrid4 = m_tree->AppendItem(subcurrid3, + text, + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + if (cbstyle & 0x20) + text = wxT("Segmentation symbols are used"); + else + text = wxT("No segmentation symbols are used"); + subcurrid4 = m_tree->AppendItem(subcurrid3, + text, + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + }; + break; + + ///////// + // QCC // + ///////// + case QCC_VAL: + { + unsigned short int cqcc; + if (csiz < 257) { + if (m_file->Read(onebyte, 1) != 1) + break; + cqcc = onebyte[0]; + } else { + if (m_file->Read(twobytes, 2) != 2) + break; + cqcc = STREAM_TO_UINT16(twobytes, 0); + } + + wxTreeItemId subcurrid = m_tree->AppendItem(currid, + wxString::Format(wxT("Comp. no. %d"), cqcc), + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + if (m_file->Read(onebyte, 1) != 1) + break; + unsigned char sqcc = onebyte[0]; + + wxString text; + switch (sqcc & 0x1F) { + case (0): + text = wxT("No quantization"); + break; + case (1): + text = wxT("Scalar implicit"); + break; + case (2): + text = wxT("Scalar explicit"); + break; + default: + text = wxT("Unknown"); + break; + } + text << wxString::Format(wxT(", %d guard bits"), (sqcc & 0xE0) >> 5); + wxTreeItemId subcurrid3 = m_tree->AppendItem(currid, + text, + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + } + break; + + ///////// + // QCD // + ///////// + case QCD_VAL: + { + if (m_file->Read(onebyte, 1) != 1) + break; + unsigned char sqcd = onebyte[0]; + + wxString text; + switch (sqcd & 0x1F) { + case (0): + text = wxT("No quantization"); + break; + case (1): + text = wxT("Scalar implicit"); + break; + case (2): + text = wxT("Scalar explicit"); + break; + default: + text = wxT("Unknown"); + break; + } + text << wxString::Format(wxT(", %d guard bits"), (sqcd & 0xE0) >> 5); + wxTreeItemId subcurrid3 = m_tree->AppendItem(currid, + text, + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + }; + break; + + ///////// + // COM // + ///////// + case COM_VAL: + { + #define showlen 25 + unsigned char comment[showlen]; + + if (m_file->Read(twobytes, 2) != 2) + break; + unsigned short int rcom = STREAM_TO_UINT16(twobytes, 0); + + wxString text; + if (rcom == 0) + text = wxT("Binary values"); + else if (rcom == 1) + text = wxT("ISO 8859-1 (latin-1) values"); + else if (rcom < 65535) + text = wxT("Reserved for registration"); + else + text = wxT("Reserved for extension"); + wxTreeItemId subcurrid3 = m_tree->AppendItem(currid, + text, + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + if (m_file->Read(comment, showlen) != showlen) + break; + subcurrid3 = m_tree->AppendItem(currid, + wxString::Format(wxT("%.*s%s"), wxMin(showlen, currlen - 4), comment, + (((currlen - 4) > showlen) ? "..." : "")), + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + }; + break; + + ///////// + // TLM // + ///////// + case TLM_VAL: + { + if (m_file->Read(onebyte, 1) != 1) + break; + unsigned char ztlm = onebyte[0]; + + if (m_file->Read(onebyte, 1) != 1) + break; + unsigned char stlm = onebyte[0]; + + image = m_tree->TreeCtrlIcon_File; + imageSel = image + 1; + + wxTreeItemId subcurrid3 = m_tree->AppendItem(currid, + wxString::Format(wxT("TLM #%d"), ztlm), + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + subcurrid3 = m_tree->AppendItem(currid, + wxString::Format(wxT("%d bits/index, %d bits/length"), + 8 * ((stlm & 0x30) >> 4), 16 + 16 * ((stlm & 0x40) >> 6)), + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + int n, numparts; + + numparts = (currlen - 2) / ( ((stlm & 0x30) >> 4) + 2 + 2 * ((stlm & 0x40) >> 6)); + + image = m_tree->TreeCtrlIcon_Folder; + imageSel = image + 1; + + subcurrid3 = m_tree->AppendItem(currid, + wxT("Tile parts"), + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + image = m_tree->TreeCtrlIcon_File; + imageSel = image + 1; + + for (n = 0; n < numparts; n++) { + + unsigned short int ttlm; + unsigned long int ptlm; + + switch (((stlm & 0x30) >> 4)) { + + case 0: + ttlm = 0; + break; + + case 1: if (m_file->Read(onebyte, 1) != 1) break; - unsigned char ssiz = onebyte[0]; - - wxTreeItemId subcurrid3 = m_tree->AppendItem(currid, - wxString::Format(wxT("%d x %d, %d comps. @ %d bpp"), xsiz, ysiz, csiz, (ssiz + 1) & 0xEF), - image, imageSel, - new OPJMarkerData(wxT("INFO")) - ); + ttlm = onebyte[0]; + break; - } + case 2: + if (m_file->Read(twobytes, 2) != 2) + break; + ttlm = STREAM_TO_UINT16(twobytes, 0); break; - case SOT_VAL: - { + } + + switch (((stlm & 0x40) >> 6)) { + + case 0: if (m_file->Read(twobytes, 2) != 2) break; - unsigned short int isot = STREAM_TO_UINT16(twobytes, 0); + ptlm = STREAM_TO_UINT16(twobytes, 0); + break; + case 1: if (m_file->Read(fourbytes, 4) != 4) break; - unsigned long int psot = STREAM_TO_UINT32(fourbytes, 0); + ptlm = STREAM_TO_UINT32(fourbytes, 0); + break; - if (m_file->Read(onebyte, 1) != 1) - break; - unsigned char tpsot = onebyte[0]; + } + + wxTreeItemId subcurrid4 = m_tree->AppendItem(subcurrid3, + wxString::Format(wxT("Tile %d: %d bytes"), ttlm, ptlm), + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + } + + } + break; + + ///////// + // POD // + ///////// + case POD_VAL: + { + int n, numchanges; + + if (csiz < 257) + numchanges = (currlen - 2) / 7; + else + numchanges = (currlen - 2) / 9; + + for (n = 0; n < numchanges; n++) { + + image = m_tree->TreeCtrlIcon_Folder; + imageSel = image + 1; + + wxTreeItemId subcurrid3 = m_tree->AppendItem(currid, + wxString::Format(wxT("Change #%d"), n), + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + if (m_file->Read(onebyte, 1) != 1) + break; + unsigned char rspod = onebyte[0]; + + unsigned short int cspod; + if (csiz < 257) { if (m_file->Read(onebyte, 1) != 1) break; - unsigned char tnsot = onebyte[0]; - - wxTreeItemId subcurrid3 = m_tree->AppendItem(currid, - wxString::Format(wxT("tile %d, psot = %d, part %d of %d"), isot, psot, tpsot, tnsot), - image, imageSel, - new OPJMarkerData(wxT("INFO")) - ); + cspod = onebyte[0]; + } else { + if (m_file->Read(twobytes, 2) != 2) + break; + cspod = STREAM_TO_UINT16(twobytes, 0); + } - lastPsot = psot; - lastsotpos = offset; - }; + if (m_file->Read(twobytes, 2) != 2) break; + unsigned short int lyepod = STREAM_TO_UINT16(twobytes, 0); - case CME_VAL: - { - #define showlen 25 - unsigned char comment[showlen]; + if (m_file->Read(onebyte, 1) != 1) + break; + unsigned char repod = onebyte[0]; - m_file->Seek(2, wxFromCurrent); - if (m_file->Read(comment, showlen) != showlen) + unsigned short int cepod; + if (csiz < 257) { + if (m_file->Read(onebyte, 1) != 1) + break; + cepod = onebyte[0]; + } else { + if (m_file->Read(twobytes, 2) != 2) break; + cepod = STREAM_TO_UINT16(twobytes, 0); + } - wxTreeItemId subcurrid3 = m_tree->AppendItem(currid, - wxString::Format(wxT("%.*s%s"), wxMin(showlen, currlen - 4), comment, - (((currlen - 4) > showlen) ? "..." : "")), - image, imageSel, - new OPJMarkerData(wxT("INFO")) - ); - } + if (m_file->Read(onebyte, 1) != 1) break; + unsigned char ppod = onebyte[0]; + + image = m_tree->TreeCtrlIcon_File; + imageSel = image + 1; + + wxTreeItemId subcurrid4 = m_tree->AppendItem(subcurrid3, + wxString::Format(wxT("%d <= Resolution < %d"), rspod, repod), + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + subcurrid4 = m_tree->AppendItem(subcurrid3, + wxString::Format(wxT("%d <= Component < %d"), cspod, cepod), + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + + subcurrid4 = m_tree->AppendItem(subcurrid3, + wxString::Format(wxT("0 <= Layer < %d"), lyepod), + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + wxString text = wxT(""); + switch (ppod) { + case (0): + text << wxT("LRCP"); + break; + case (1): + text << wxT("RLCP"); + break; + case (2): + text << wxT("LRCP"); + break; + case (3): + text << wxT("RPCL"); + break; + case (4): + text << wxT("CPRL"); + break; default: + text << wxT("unknown progression"); break; } - - - // increment number of markers - nmarks++; - if (nmarks >= maxmarks) - break; + subcurrid4 = m_tree->AppendItem(subcurrid3, + text, + image, imageSel, + new OPJMarkerData(wxT("INFO")) + ); + } - // increment offset - if (currmark == SOD_VAL) - offset += lastPsot - (offset - lastsotpos); - else - offset += (2 + currlen); + } + break; - m_file->Seek(offset, wxFromStart); - done = 1; + ///////// + // SOD // + ///////// + case SOD_VAL: + { + inside_sod = 1; + }; + break; - break; - } + default: + break; + } - - if (done) - continue; - else { - offset++; - m_file->Seek(offset, wxFromStart); + + // increment number of markers + if (nmarks++ >= maxmarks) { + WriteText(wxT("Maximum amount of markers exceeded")); + break; } - } - + + // advance position + OPJ_ADVANCE(currlen + 2); + } + + WriteText(wxT("Search finished")); } -- cgit v1.2.3