Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Copyright (c) 2007, Digital Signal Processing Laboratory, Università degli studi di Perugia (UPG), Italy
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice, this list of conditions and the following disclaimer in the
  12.  *    documentation and/or other materials provided with the distribution.
  13.  *
  14.  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
  15.  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  16.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  17.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  18.  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  19.  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  20.  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  21.  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  22.  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  23.  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  24.  * POSSIBILITY OF SUCH DAMAGE.
  25.  */
  26. #include "OPJViewer.h"
  27.  
  28. /* From little endian to big endian, 2 bytes */
  29. #define BYTE_SWAP2(X)   ((X & 0x00FF) << 8) | ((X & 0xFF00) >> 8)
  30. #define BYTE_SWAP4(X)   ((X & 0x000000FF) << 24) | ((X & 0x0000FF00) << 8) | ((X & 0x00FF0000) >> 8) | ((X & 0xFF000000) >> 24)
  31.  
  32. /* From codestream to int values */
  33. #define STREAM_TO_UINT32(C, P)  (((unsigned long int) (C)[(P) + 0] << 24) + \
  34.                                                                 ((unsigned long int) (C)[(P) + 1] << 16) + \
  35.                                                                 ((unsigned long int) (C)[(P) + 2] << 8) + \
  36.                                                                 ((unsigned long int) (C)[(P) + 3] << 0))
  37.  
  38. #define STREAM_TO_UINT16(C, P)  (((unsigned long int) (C)[(P) + 0] << 8) + \
  39.                                                                 ((unsigned long int) (C)[(P) + 1] << 0))
  40.  
  41.  
  42. /* Markers values */
  43. #define J2KMARK_NUM 24
  44. enum {
  45.         SOC_VAL = 0xFF4F,
  46.         SOT_VAL = 0xFF90,
  47.         SOD_VAL = 0xFF93,
  48.         EOC_VAL = 0xFFD9,
  49.         SIZ_VAL = 0xFF51,
  50.         COD_VAL = 0xFF52,
  51.         COC_VAL = 0xFF53,
  52.         RGN_VAL = 0xFF5E,
  53.         QCD_VAL = 0xFF5C,
  54.         QCC_VAL = 0xFF5D,
  55.         POD_VAL = 0xFF5F,
  56.         TLM_VAL = 0xFF55,
  57.         PLM_VAL = 0xFF57,
  58.         PLT_VAL = 0xFF58,
  59.         PPM_VAL = 0xFF60,
  60.         PPT_VAL = 0xFF61,
  61.         SOP_VAL = 0xFF91,
  62.         EPH_VAL = 0xFF92,
  63.         COM_VAL = 0xFF64
  64. #ifdef USE_JPWL
  65.         , EPB_VAL       = 0xFF66,
  66.         ESD_VAL = 0xFF67,
  67.         EPC_VAL = 0xFF68,
  68.         RED_VAL = 0xFF69
  69.         /*, EPB_VAL = 0xFF96,
  70.         ESD_VAL = 0xFF98,
  71.         EPC_VAL = 0xFF97,
  72.         RED_VAL = 0xFF99*/
  73. #endif // USE_JPWL
  74. #ifdef USE_JPSEC
  75.         , SEC_VAL = 0xFF65
  76. #endif // USE_JPSEC
  77. };
  78.  
  79. // All the markers in one vector
  80. unsigned short int marker_val[] = {
  81.         SOC_VAL, SOT_VAL, SOD_VAL, EOC_VAL,
  82.         SIZ_VAL,
  83.         COD_VAL, COC_VAL, RGN_VAL, QCD_VAL, QCC_VAL, POD_VAL,
  84.         TLM_VAL, PLM_VAL, PLT_VAL, PPM_VAL, PPT_VAL,
  85.         SOP_VAL, EPH_VAL,
  86.         COM_VAL
  87. #ifdef USE_JPWL
  88.         , EPB_VAL, ESD_VAL, EPC_VAL, RED_VAL
  89. #endif // USE_JPWL
  90. #ifdef USE_JPSEC
  91.         , SEC_VAL
  92. #endif // USE_JPSEC
  93. };
  94.  
  95. // Marker names
  96. char *marker_name[] = {
  97.         "SOC", "SOT", "SOD", "EOC",
  98.         "SIZ",
  99.         "COD", "COC", "RGN", "QCD", "QCC", "POD",
  100.         "TLM", "PLM", "PLT", "PPM", "PPT",
  101.         "SOP", "EPH",
  102.         "COM"
  103. #ifdef USE_JPWL
  104.         , "EPB", "ESD", "EPC", "RED"
  105. #endif // USE_JPWL
  106. #ifdef USE_JPSEC
  107.         , "SEC"
  108. #endif // USE_JPSEC
  109. };
  110.  
  111. // Marker descriptions
  112. char *marker_descr[] = {
  113.         "Start of codestream", "Start of tile-part", "Start of data", "End of codestream",
  114.         "Image and tile size",
  115.         "Coding style default", "Coding style component", "Region-of-interest", "Quantization default",
  116.         "Quantization component", "Progression order change, default",
  117.         "Tile-part lengths, main header", "Packet length, main header", "Packets length, tile-part header",
  118.         "Packed packet headers, main header", "Packed packet headers, tile-part header",
  119.         "Start of packet", "End of packet header",
  120.         "Comment and extension"
  121. #ifdef USE_JPWL
  122.         , "Error Protection Block", "Error Sensitivity Descriptor", "Error Protection Capability",
  123.         "Residual Errors Descriptor"
  124. #endif // USE_JPWL
  125. #ifdef USE_JPSEC
  126.         , "Main security marker"
  127. #endif // USE_JPSEC
  128. };
  129.  
  130. void OPJParseThread::ParseJ2KFile(wxFile *m_file, wxFileOffset offset, wxFileOffset length, wxTreeItemId parentid)
  131. {
  132.         unsigned short int csiz = 0;
  133.  
  134.         // check if the file is opened
  135.         if (m_file->IsOpened())
  136.                 WriteText(wxT("File OK"));
  137.         else
  138.                 return;
  139.  
  140.         // position at the beginning
  141.         m_file->Seek(offset, wxFromStart);
  142.  
  143.         // navigate the file
  144.         int m, inside_sod = 0, inside_sop = 0;
  145.         int nmarks = 0, maxmarks = 10000;
  146.         unsigned char onebyte[1];
  147.         unsigned char twobytes[2], firstbyte, secondbyte;
  148.         unsigned char fourbytes[4];
  149.         unsigned short int currmark;
  150.         unsigned short int currlen;
  151.         int lastPsot = 0, lastsotpos = 0;
  152.  
  153.         WriteText(wxT("Start search..."));
  154.  
  155. // advancing macro
  156. #define OPJ_ADVANCE(A) {offset += A; if (offset < length) m_file->Seek(offset, wxFromStart); else return;}
  157.  
  158.         // begin search
  159.         while ((offset < length) && (!m_file->Eof())) {
  160.  
  161.                 // read one byte
  162.                 if (m_file->Read(&firstbyte, 1) != 1)
  163.                         break;
  164.  
  165.                 // look for 0xFF
  166.                 if (firstbyte == 0xFF) {
  167.  
  168.                         // it is a possible marker
  169.                         if (m_file->Read(&secondbyte, 1) != 1)
  170.                                 break;
  171.                         else
  172.                                 currmark = (((unsigned short int) firstbyte) << 8) + (unsigned short int) secondbyte;
  173.  
  174.                 } else {
  175.  
  176.                         // nope, advance by one and search again
  177.                         OPJ_ADVANCE(1);
  178.                         continue;
  179.                 }
  180.                
  181.                 // search the marker
  182.                 for (m = 0; m < J2KMARK_NUM; m++) {
  183.                         if (currmark == marker_val[m])
  184.                                 break;
  185.                 }
  186.  
  187.                 // marker not found
  188.                 if (m == J2KMARK_NUM) {
  189.                         // nope, advance by one and search again
  190.                         OPJ_ADVANCE(1);
  191.                         continue;
  192.                 }
  193.  
  194.                 // if we are inside SOD, only some markers are allowed
  195.                 if (inside_sod) {
  196.  
  197.                         // we are inside SOP
  198.                         if (inside_sop) {
  199.  
  200.                         }
  201.  
  202.                         // randomly marker coincident data
  203.                         if ((currmark != SOT_VAL) &&
  204.                                 (currmark != EOC_VAL) &&
  205.                                 (currmark != SOP_VAL) &&
  206.                                 (currmark != EPH_VAL)) {
  207.                                 OPJ_ADVANCE(1);
  208.                                 continue;
  209.                         }
  210.  
  211.                         // possible SOT?
  212.                         if ((currmark == SOT_VAL)) {
  213.                                 // too early SOT
  214.                                 if (offset < (lastsotpos + lastPsot)) {
  215.                                         OPJ_ADVANCE(1);
  216.                                         continue;
  217.                                 }
  218.                                 // we were not in the last tile
  219.                                 /*if (lastPsot != 0) {
  220.                                         OPJ_ADVANCE(1);
  221.                                         break;
  222.                                 }*/
  223.                         }
  224.                 }
  225.  
  226.                 // beyond this point, the marker MUST BE real
  227.  
  228.                 // length of current marker segment
  229.                 if ((currmark == SOD_VAL) ||
  230.                         (currmark == SOC_VAL) ||
  231.                         (currmark == EOC_VAL) ||
  232.                         (currmark == EPH_VAL))
  233.  
  234.                         // zero length markers
  235.                         currlen = 0;
  236.  
  237.                 else {
  238.  
  239.                         // read length field
  240.                         if (m_file->Read(twobytes, 2) != 2)
  241.                                 break;
  242.  
  243.                         currlen = (((unsigned short int) twobytes[0]) << 8) + (unsigned short int) twobytes[1];
  244.                 }
  245.  
  246.                 // here we pass to AppendItem() normal and selected item images (we
  247.                 // suppose that selected image follows the normal one in the enum)
  248.                 int image, imageSel;
  249.                 image = m_tree->TreeCtrlIcon_Folder;
  250.                 imageSel = image + 1;
  251.  
  252.                 // append the marker
  253.                 wxTreeItemId currid = m_tree->AppendItem(parentid,
  254.                         wxString::Format(wxT("%03d: "), nmarks) +
  255.                         wxString::FromAscii(marker_name[m]) +
  256.                         wxString::Format(wxT(" (0x%04X)"), marker_val[m]),
  257.                         image, imageSel,
  258.                         new OPJMarkerData(wxT("MARK") + wxString::Format(wxT(" (%d)"), marker_val[m]),
  259.                                 m_tree->m_fname.GetFullPath(), offset, offset + currlen + 1)
  260.                         );
  261.  
  262.                 // append some info
  263.                 image = m_tree->TreeCtrlIcon_File;
  264.                 imageSel = image + 1;
  265.  
  266.                 // marker name
  267.                 wxTreeItemId subcurrid1 = m_tree->AppendItem(currid,
  268.                         wxT("*** ") + wxString::FromAscii(marker_descr[m]) + wxT(" ***"),
  269.                         image, imageSel,
  270.                         new OPJMarkerData(wxT("INFO"))
  271.                         );
  272.                 m_tree->SetItemFont(subcurrid1, *wxITALIC_FONT);
  273.  
  274.                 // position and length
  275.                 wxTreeItemId subcurrid2 = m_tree->AppendItem(currid,
  276.                         wxLongLong(offset).ToString() + wxT(" > ") + wxLongLong(offset + currlen + 1).ToString() +
  277.                         wxT(", ") + wxString::Format(wxT("%d + 2 (%d)"), currlen, currlen + 2),
  278.                         image, imageSel,
  279.                         new OPJMarkerData(wxT("INFO"))
  280.                         );
  281.  
  282.                 // give additional info on markers
  283.                 switch (currmark) {
  284.  
  285.                 /////////
  286.                 // SOP //
  287.                 /////////
  288.                 case SOP_VAL:
  289.                         {
  290.                         // read packet number
  291.                         if (m_file->Read(twobytes, 2) != 2)
  292.                                 break;
  293.                         int packnum = STREAM_TO_UINT16(twobytes, 0);
  294.  
  295.                         image = m_tree->TreeCtrlIcon_File;
  296.                         imageSel = image + 1;
  297.  
  298.                         wxTreeItemId subcurrid3 = m_tree->AppendItem(currid,
  299.                                 wxString::Format(wxT("Pack. no. %d"), packnum),
  300.                                 image, imageSel,
  301.                                 new OPJMarkerData(wxT("INFO"))
  302.                                 );
  303.                         inside_sop = 1;
  304.                         };
  305.                         break;
  306.  
  307. #ifdef USE_JPWL
  308.                 /////////
  309.                 // RED //
  310.                 /////////
  311.                 case RED_VAL:
  312.                         {
  313.                         if (m_file->Read(onebyte, 1) != 1)
  314.                                 break;
  315.                         unsigned char pred = onebyte[0];
  316.  
  317.                         image = m_tree->TreeCtrlIcon_File;
  318.                         imageSel = image + 1;
  319.  
  320.                         wxString address[] = {
  321.                                 wxT("Packet addressing"),
  322.                                 wxT("Byte-range addressing"),
  323.                                 wxT("Packet-range addressing"),
  324.                                 wxT("Reserved")
  325.                         };
  326.  
  327.                         wxTreeItemId subcurrid = m_tree->AppendItem(currid,
  328.                                 address[(pred & 0xC0) >> 6],
  329.                                 image, imageSel,
  330.                                 new OPJMarkerData(wxT("INFO"))
  331.                                 );
  332.  
  333.                         subcurrid = m_tree->AppendItem(currid,
  334.                                 wxString::Format(wxT("%d bytes range"), (((pred & 0x02) >> 1) + 1) * 2),
  335.                                 image, imageSel,
  336.                                 new OPJMarkerData(wxT("INFO"))
  337.                                 );
  338.  
  339.                         subcurrid = m_tree->AppendItem(currid,
  340.                                 pred & 0x01 ? wxT("Errors/erasures in codestream") : wxT("Error free codestream"),
  341.                                 image, imageSel,
  342.                                 new OPJMarkerData(wxT("INFO"))
  343.                                 );
  344.  
  345.                         subcurrid = m_tree->AppendItem(currid,
  346.                                 wxString::Format(wxT("Residual corruption level: %d"), (pred & 0x38) >> 3),
  347.                                 image, imageSel,
  348.                                 new OPJMarkerData(wxT("INFO"))
  349.                                 );
  350.  
  351.                         }
  352.                         break;
  353.  
  354.                 /////////
  355.                 // ESD //
  356.                 /////////
  357.                 case ESD_VAL:
  358.                         {
  359.                         unsigned short int cesd;
  360.                         if (csiz < 257) {
  361.                                 if (m_file->Read(onebyte, 1) != 1)
  362.                                         break;
  363.                                 cesd = onebyte[0];
  364.                         } else {
  365.                                 if (m_file->Read(twobytes, 2) != 2)
  366.                                         break;
  367.                                 cesd = STREAM_TO_UINT16(twobytes, 0);
  368.                         }
  369.  
  370.                         if (m_file->Read(onebyte, 1) != 1)
  371.                                 break;
  372.                         unsigned char pesd = onebyte[0];
  373.  
  374.                         image = m_tree->TreeCtrlIcon_File;
  375.                         imageSel = image + 1;
  376.  
  377.                         wxTreeItemId subcurrid = m_tree->AppendItem(currid,
  378.                                 pesd & 0x01 ? wxT("Comp. average") : wxString::Format(wxT("Comp. no. %d"), cesd),
  379.                                 image, imageSel,
  380.                                 new OPJMarkerData(wxT("INFO"))
  381.                                 );
  382.  
  383.                         wxString meth[] = {
  384.                                 wxT("Relative error sensitivity"),
  385.                                 wxT("MSE"),
  386.                                 wxT("MSE reduction"),
  387.                                 wxT("PSNR"),
  388.                                 wxT("PSNR increase"),
  389.                                 wxT("MAXERR (absolute peak error)"),
  390.                                 wxT("TSE (total squared error)"),
  391.                                 wxT("Reserved")
  392.                         };
  393.  
  394.                         subcurrid = m_tree->AppendItem(currid,
  395.                                 meth[(pesd & 0x38) >> 3],
  396.                                 image, imageSel,
  397.                                 new OPJMarkerData(wxT("INFO"))
  398.                                 );
  399.  
  400.                         wxString address[] = {
  401.                                 wxT("Packet addressing"),
  402.                                 wxT("Byte-range addressing"),
  403.                                 wxT("Packet-range addressing"),
  404.                                 wxT("Reserved")
  405.                         };
  406.  
  407.                         subcurrid = m_tree->AppendItem(currid,
  408.                                 address[(pesd & 0xC0) >> 6],
  409.                                 image, imageSel,
  410.                                 new OPJMarkerData(wxT("INFO"))
  411.                                 );
  412.  
  413.                         subcurrid = m_tree->AppendItem(currid,
  414.                                 wxString::Format(wxT("%d bytes/value, %d bytes range"), ((pesd & 0x04) >> 2) + 1, (((pesd & 0x02) >> 1) + 1) * 2),
  415.                                 image, imageSel,
  416.                                 new OPJMarkerData(wxT("INFO"))
  417.                                 );
  418.  
  419.                         }
  420.                         break;
  421.  
  422.                 /////////
  423.                 // EPC //
  424.                 /////////
  425.                 case EPC_VAL:
  426.                         {
  427.                         if (m_file->Read(twobytes, 2) != 2)
  428.                                 break;
  429.                         unsigned short int pcrc = STREAM_TO_UINT16(twobytes, 0);
  430.  
  431.                         if (m_file->Read(fourbytes, 4) != 4)
  432.                                 break;
  433.                         unsigned long int dl = STREAM_TO_UINT32(fourbytes, 0);
  434.  
  435.                         if (m_file->Read(onebyte, 1) != 1)
  436.                                 break;
  437.                         unsigned char pepc = onebyte[0];
  438.  
  439.                         image = m_tree->TreeCtrlIcon_File;
  440.                         imageSel = image + 1;
  441.  
  442.                         wxTreeItemId subcurrid = m_tree->AppendItem(currid,
  443.                                 wxString::Format(wxT("CRC-16 = 0x%x"), pcrc),
  444.                                 image, imageSel,
  445.                                 new OPJMarkerData(wxT("INFO"))
  446.                                 );
  447.  
  448.                         subcurrid = m_tree->AppendItem(currid,
  449.                                 wxString::Format(wxT("Tot. length = %d"), dl),
  450.                                 image, imageSel,
  451.                                 new OPJMarkerData(wxT("INFO"))
  452.                                 );
  453.  
  454.                         subcurrid = m_tree->AppendItem(currid,
  455.                                 wxString::Format(wxT("%s%s%s%s"),
  456.                                         pepc & 0x10 ? wxT("ESD, ") : wxT(""),
  457.                                         pepc & 0x20 ? wxT("RED, ") : wxT(""),
  458.                                         pepc & 0x40 ? wxT("EPB, ") : wxT(""),
  459.                                         pepc & 0x80 ? wxT("Info") : wxT("")
  460.                                         ),
  461.                                 image, imageSel,
  462.                                 new OPJMarkerData(wxT("INFO"))
  463.                                 );
  464.  
  465.                         }
  466.                         break;
  467.  
  468.                 /////////
  469.                 // EPB //
  470.                 /////////
  471.                 case EPB_VAL:
  472.                         {
  473.                         if (m_file->Read(onebyte, 1) != 1)
  474.                                 break;
  475.                         unsigned char depb = onebyte[0];
  476.  
  477.                         if (m_file->Read(fourbytes, 4) != 4)
  478.                                 break;
  479.                         unsigned long int ldpepb = STREAM_TO_UINT32(fourbytes, 0);
  480.  
  481.                         if (m_file->Read(fourbytes, 4) != 4)
  482.                                 break;
  483.                         unsigned long int pepb = STREAM_TO_UINT32(fourbytes, 0);
  484.  
  485.                         image = m_tree->TreeCtrlIcon_File;
  486.                         imageSel = image + 1;
  487.  
  488.                         wxTreeItemId subcurrid = m_tree->AppendItem(currid,
  489.                                 wxString::Format(wxT("No. %d, %slatest, %spacked"),
  490.                                         depb & 0x3F,
  491.                                         depb & 0x40 ? wxT("") : wxT("not "),
  492.                                         depb & 0x80 ? wxT("") : wxT("un")),
  493.                                 image, imageSel,
  494.                                 new OPJMarkerData(wxT("INFO"))
  495.                                 );
  496.  
  497.                         subcurrid = m_tree->AppendItem(currid,
  498.                                 wxString::Format(wxT("%d bytes protected"), ldpepb),
  499.                                 image, imageSel,
  500.                                 new OPJMarkerData(wxT("INFO"))
  501.                                 );
  502.  
  503.                         if (pepb == 0x00000000)
  504.  
  505.                                 subcurrid = m_tree->AppendItem(currid,
  506.                                         wxT("Predefined codes"),
  507.                                         image, imageSel,
  508.                                         new OPJMarkerData(wxT("INFO"))
  509.                                         );
  510.  
  511.                         else if ((pepb >= 0x10000000) && (pepb <= 0x1FFFFFFF)) {
  512.  
  513.                                 wxString text = wxT("CRC code");
  514.                                 if (pepb == 0x10000000)
  515.                                         text << wxT(", CCITT (X25) 16 bits");
  516.                                 else if (pepb == 0x10000001)
  517.                                         text << wxT(", Ethernet 32 bits");
  518.                                 else
  519.                                         text << wxT(", JPWL RA");
  520.                                 subcurrid = m_tree->AppendItem(currid,
  521.                                         text,
  522.                                         image, imageSel,
  523.                                         new OPJMarkerData(wxT("INFO"))
  524.                                         );
  525.  
  526.                         } else if ((pepb >= 0x20000000) && (pepb <= 0x2FFFFFFF)) {
  527.  
  528.                                 wxString text;
  529.                                 subcurrid = m_tree->AppendItem(currid,
  530.                                         wxString::Format(wxT("RS code, RS(%d, %d)"),
  531.                                                 (pepb & 0x0000FF00) >> 8,
  532.                                                 (pepb & 0x000000FF)),
  533.                                         image, imageSel,
  534.                                         new OPJMarkerData(wxT("INFO"))
  535.                                         );
  536.  
  537.                         } else if ((pepb >= 0x30000000) && (pepb <= 0x3FFFFFFE))
  538.  
  539.                                 subcurrid = m_tree->AppendItem(currid,
  540.                                         wxT("JPWL RA"),
  541.                                         image, imageSel,
  542.                                         new OPJMarkerData(wxT("INFO"))
  543.                                         );
  544.  
  545.                         else if (pepb == 0xFFFFFFFF)
  546.  
  547.                                 subcurrid = m_tree->AppendItem(currid,
  548.                                         wxT("No method"),
  549.                                         image, imageSel,
  550.                                         new OPJMarkerData(wxT("INFO"))
  551.                                         );
  552.  
  553.                         }
  554.                         break;
  555. #endif // USE_JPWL
  556.  
  557. #ifdef USE_JPSEC
  558.                 case SEC_VAL:
  559.                         {
  560.  
  561.                         }
  562.                         break;
  563. #endif // USE_JPSEC
  564.  
  565.                 /////////
  566.                 // SIZ //
  567.                 /////////
  568.                 case SIZ_VAL:
  569.                         {
  570.                         int c;
  571.                        
  572.                         if (m_file->Read(twobytes, 2) != 2)
  573.                                 break;
  574.                         unsigned short int rsiz = STREAM_TO_UINT16(twobytes, 0);
  575.  
  576.                         if (m_file->Read(fourbytes, 4) != 4)
  577.                                 break;
  578.                         unsigned long int xsiz = STREAM_TO_UINT32(fourbytes, 0);
  579.  
  580.                         if (m_file->Read(fourbytes, 4) != 4)
  581.                                 break;
  582.                         unsigned long int ysiz = STREAM_TO_UINT32(fourbytes, 0);
  583.  
  584.                         if (m_file->Read(fourbytes, 4) != 4)
  585.                                 break;
  586.                         unsigned long int xosiz = STREAM_TO_UINT32(fourbytes, 0);
  587.  
  588.                         if (m_file->Read(fourbytes, 4) != 4)
  589.                                 break;
  590.                         unsigned long int yosiz = STREAM_TO_UINT32(fourbytes, 0);
  591.  
  592.                         if (m_file->Read(fourbytes, 4) != 4)
  593.                                 break;
  594.                         unsigned long int xtsiz = STREAM_TO_UINT32(fourbytes, 0);
  595.                         this->m_tree->m_childframe->m_twidth = xtsiz;
  596.  
  597.                         if (m_file->Read(fourbytes, 4) != 4)
  598.                                 break;
  599.                         unsigned long int ytsiz = STREAM_TO_UINT32(fourbytes, 0);
  600.                         this->m_tree->m_childframe->m_theight = ytsiz;
  601.  
  602.                         if (m_file->Read(fourbytes, 4) != 4)
  603.                                 break;
  604.                         unsigned long int xtosiz = STREAM_TO_UINT32(fourbytes, 0);
  605.                         this->m_tree->m_childframe->m_tx = xtosiz;
  606.  
  607.                         if (m_file->Read(fourbytes, 4) != 4)
  608.                                 break;
  609.                         unsigned long int ytosiz = STREAM_TO_UINT32(fourbytes, 0);
  610.                         this->m_tree->m_childframe->m_ty = ytosiz;
  611.  
  612.                         if (m_file->Read(twobytes, 2) != 2)
  613.                                 break;
  614.                         csiz = STREAM_TO_UINT16(twobytes, 0);
  615.  
  616.                         bool equaldepth = true, equalsize = true;
  617.                         unsigned char *ssiz  = new unsigned char(csiz);
  618.                         unsigned char *xrsiz = new unsigned char(csiz);
  619.                         unsigned char *yrsiz = new unsigned char(csiz);
  620.  
  621.                         for (c = 0; c < csiz; c++) {
  622.  
  623.                                 if (m_file->Read(&ssiz[c], 1) != 1)
  624.                                         break;
  625.  
  626.                                 if (c > 0)
  627.                                         equaldepth = equaldepth && (ssiz[c] == ssiz[c - 1]);
  628.  
  629.                                 if (m_file->Read(&xrsiz[c], 1) != 1)
  630.                                         break;
  631.  
  632.                                 if (m_file->Read(&yrsiz[c], 1) != 1)
  633.                                         break;
  634.  
  635.                                 if (c > 0)
  636.                                         equalsize = equalsize && (xrsiz[c] == xrsiz[c - 1]) && (yrsiz[c] == yrsiz[c - 1]) ;
  637.  
  638.                         }
  639.  
  640.                         if (equaldepth && equalsize)
  641.                                 wxTreeItemId subcurrid3 = m_tree->AppendItem(currid,
  642.                                         wxString::Format(wxT("I: %dx%d (%d, %d), %d c., %d%s bpp"),
  643.                                         xsiz, ysiz,
  644.                                         xosiz, yosiz,
  645.                                         csiz, ((ssiz[0] & 0x7F) + 1),
  646.                                         (ssiz[0] & 0x80) ? wxT("s") : wxT("u")),
  647.                                         image, imageSel,
  648.                                         new OPJMarkerData(wxT("INFO"))
  649.                                         );
  650.                         else
  651.                                 wxTreeItemId subcurrid3 = m_tree->AppendItem(currid,
  652.                                         wxString::Format(wxT("I: %dx%d (%d, %d), %d c."),
  653.                                         xsiz, ysiz,
  654.                                         xosiz, yosiz,
  655.                                         csiz),
  656.                                         image, imageSel,
  657.                                         new OPJMarkerData(wxT("INFO"))
  658.                                         );
  659.  
  660.                         wxTreeItemId subcurrid3 = m_tree->AppendItem(currid,
  661.                                 wxString::Format(wxT("T: %dx%d (%d, %d)"),
  662.                                 xtsiz, ytsiz,
  663.                                 xtosiz, ytosiz),
  664.                                 image, imageSel,
  665.                                 new OPJMarkerData(wxT("INFO"))
  666.                                 );
  667.  
  668.                         image = m_tree->TreeCtrlIcon_Folder;
  669.                         imageSel = image + 1;
  670.  
  671.                         wxTreeItemId subcurrid4 = m_tree->AppendItem(currid,
  672.                                 wxT("Components"),
  673.                                 image, imageSel,
  674.                                 new OPJMarkerData(wxT("INFO"))
  675.                                 );
  676.  
  677.                         image = m_tree->TreeCtrlIcon_File;
  678.                         imageSel = image + 1;
  679.  
  680.                         for (c = 0; c < csiz; c++) {
  681.  
  682.                                 wxTreeItemId subcurrid5 = m_tree->AppendItem(subcurrid4,
  683.                                         wxString::Format(wxT("#%d: %dx%d, %d%s bpp"),
  684.                                         c,
  685.                                         xsiz/xrsiz[c], ysiz/yrsiz[c],
  686.                                         ((ssiz[c] & 0x7F) + 1),
  687.                                         (ssiz[c] & 0x80) ? wxT("s") : wxT("u")),
  688.                                         image, imageSel,
  689.                                         new OPJMarkerData(wxT("INFO"))
  690.                                         );
  691.  
  692.                         }
  693.  
  694.                         };
  695.                         break;
  696.  
  697.                 /////////
  698.                 // SOT //
  699.                 /////////
  700.                 case SOT_VAL:
  701.                         {
  702.                         if (m_file->Read(twobytes, 2) != 2)
  703.                                 break;
  704.                         unsigned short int isot = STREAM_TO_UINT16(twobytes, 0);
  705.  
  706.                         if (m_file->Read(fourbytes, 4) != 4)
  707.                                 break;
  708.                         unsigned long int psot = STREAM_TO_UINT32(fourbytes, 0);
  709.  
  710.                         if (m_file->Read(onebyte, 1) != 1)
  711.                                 break;
  712.                         unsigned char tpsot = onebyte[0];
  713.  
  714.                         if (m_file->Read(onebyte, 1) != 1)
  715.                                 break;
  716.                         unsigned char tnsot = onebyte[0];
  717.  
  718.                         wxTreeItemId subcurrid3 = m_tree->AppendItem(currid,
  719.                                 wxString::Format(wxT("tile %d, psot = %d, part %d of %d"), isot, psot, tpsot, tnsot),
  720.                                 image, imageSel,
  721.                                 new OPJMarkerData(wxT("INFO"))
  722.                                 );
  723.  
  724.                         lastPsot = psot;
  725.                         lastsotpos = offset;
  726.                         inside_sod = 0;
  727.                         };
  728.                         break;
  729.  
  730.                 /////////
  731.                 // COC //
  732.                 /////////
  733.                 case COC_VAL:
  734.                         {
  735.                         unsigned short int ccoc;
  736.                         if (csiz < 257) {
  737.                                 if (m_file->Read(onebyte, 1) != 1)
  738.                                         break;
  739.                                 ccoc = onebyte[0];
  740.                         } else {
  741.                                 if (m_file->Read(twobytes, 2) != 2)
  742.                                         break;
  743.                                 ccoc = STREAM_TO_UINT16(twobytes, 0);
  744.                         }
  745.  
  746.                         if (m_file->Read(onebyte, 1) != 1)
  747.                                 break;
  748.                         unsigned char scoc = onebyte[0];
  749.  
  750.                         wxTreeItemId subcurrid = m_tree->AppendItem(currid,
  751.                                 wxString::Format(wxT("Comp. no. %d"), ccoc),
  752.                                 image, imageSel,
  753.                                 new OPJMarkerData(wxT("INFO"))
  754.                                 );
  755.                        
  756.                         wxString text;
  757.                         if (scoc & 0x01)
  758.                                 text << wxT("Partitioned entropy coder");
  759.                         else
  760.                                 text << wxT("Unpartitioned entropy coder");
  761.  
  762.                         subcurrid = m_tree->AppendItem(currid,
  763.                                 text,
  764.                                 image, imageSel,
  765.                                 new OPJMarkerData(wxT("INFO"))
  766.                                 );
  767.  
  768.                         if (m_file->Read(onebyte, 1) != 1)
  769.                                 break;
  770.                         unsigned char decomplevs = onebyte[0];
  771.  
  772.                         if (m_file->Read(onebyte, 1) != 1)
  773.                                 break;
  774.                         unsigned char cbswidth = onebyte[0];
  775.  
  776.                         if (m_file->Read(onebyte, 1) != 1)
  777.                                 break;
  778.                         unsigned char cbsheight = onebyte[0];
  779.  
  780.                         if (m_file->Read(onebyte, 1) != 1)
  781.                                 break;
  782.                         unsigned char cbstyle = onebyte[0];
  783.  
  784.                         if (m_file->Read(onebyte, 1) != 1)
  785.                                 break;
  786.                         unsigned char transform = onebyte[0];
  787.  
  788.                         subcurrid = m_tree->AppendItem(currid,
  789.                                 wxString::Format(wxT("%d levels (%d resolutions)"), decomplevs, decomplevs + 1),
  790.                                 image, imageSel,
  791.                                 new OPJMarkerData(wxT("INFO"))
  792.                                 );
  793.  
  794.                         if (transform & 0x01)
  795.                                 text = wxT("5-3 reversible wavelet");
  796.                         else
  797.                                 text = wxT("9-7 irreversible wavelet");
  798.                         subcurrid = m_tree->AppendItem(currid,
  799.                                 text,
  800.                                 image, imageSel,
  801.                                 new OPJMarkerData(wxT("INFO"))
  802.                                 );
  803.  
  804.                         subcurrid = m_tree->AppendItem(currid,
  805.                                 wxString::Format(wxT("Code-blocks: %dx%d"), 1 << ((cbswidth & 0x0F) + 2), 1 << ((cbsheight & 0x0F) + 2)),
  806.                                 image, imageSel,
  807.                                 new OPJMarkerData(wxT("INFO"))
  808.                                 );
  809.  
  810.                         image = m_tree->TreeCtrlIcon_Folder;
  811.                         imageSel = image + 1;
  812.  
  813.                         wxTreeItemId subcurrid3 = m_tree->AppendItem(currid,
  814.                                 wxT("Coding styles"),
  815.                                 image, imageSel,
  816.                                 new OPJMarkerData(wxT("INFO"))
  817.                                 );
  818.  
  819.                         image = m_tree->TreeCtrlIcon_File;
  820.                         imageSel = image + 1;
  821.  
  822.                         if (cbstyle & 0x01)
  823.                                 text = wxT("Selective arithmetic coding bypass");
  824.                         else
  825.                                 text = wxT("No selective arithmetic coding bypass");
  826.                         wxTreeItemId subcurrid4 = m_tree->AppendItem(subcurrid3,
  827.                                 text,
  828.                                 image, imageSel,
  829.                                 new OPJMarkerData(wxT("INFO"))
  830.                                 );
  831.  
  832.                         if (cbstyle & 0x02)
  833.                                 text = wxT("Reset context probabilities on coding pass boundaries");
  834.                         else
  835.                                 text = wxT("No reset of context probabilities on coding pass boundaries");
  836.                         subcurrid4 = m_tree->AppendItem(subcurrid3,
  837.                                 text,
  838.                                 image, imageSel,
  839.                                 new OPJMarkerData(wxT("INFO"))
  840.                                 );
  841.  
  842.                         if (cbstyle & 0x04)
  843.                                 text = wxT("Termination on each coding passs");
  844.                         else
  845.                                 text = wxT("No termination on each coding pass");
  846.                         subcurrid4 = m_tree->AppendItem(subcurrid3,
  847.                                 text,
  848.                                 image, imageSel,
  849.                                 new OPJMarkerData(wxT("INFO"))
  850.                                 );
  851.  
  852.                         if (cbstyle & 0x08)
  853.                                 text = wxT("Vertically stripe causal context");
  854.                         else
  855.                                 text = wxT("No vertically stripe causal context");
  856.                         subcurrid4 = m_tree->AppendItem(subcurrid3,
  857.                                 text,
  858.                                 image, imageSel,
  859.                                 new OPJMarkerData(wxT("INFO"))
  860.                                 );
  861.  
  862.                         if (cbstyle & 0x10)
  863.                                 text = wxT("Predictable termination");
  864.                         else
  865.                                 text = wxT("No predictable termination");
  866.                         subcurrid4 = m_tree->AppendItem(subcurrid3,
  867.                                 text,
  868.                                 image, imageSel,
  869.                                 new OPJMarkerData(wxT("INFO"))
  870.                                 );
  871.  
  872.                         if (cbstyle & 0x20)
  873.                                 text = wxT("Segmentation symbols are used");
  874.                         else
  875.                                 text = wxT("No segmentation symbols are used");
  876.                         subcurrid4 = m_tree->AppendItem(subcurrid3,
  877.                                 text,
  878.                                 image, imageSel,
  879.                                 new OPJMarkerData(wxT("INFO"))
  880.                                 );
  881.  
  882.                         }
  883.                         break;
  884.  
  885.                 /////////
  886.                 // COD //
  887.                 /////////
  888.                 case COD_VAL:
  889.                         {
  890.                         if (m_file->Read(onebyte, 1) != 1)
  891.                                 break;
  892.                         unsigned char scod = onebyte[0];
  893.  
  894.                         wxString text;
  895.  
  896.                         if (scod & 0x01)
  897.                                 text << wxT("Partitioned entropy coder");
  898.                         else
  899.                                 text << wxT("Unpartitioned entropy coder");
  900.  
  901.                         wxTreeItemId subcurrid3 = m_tree->AppendItem(currid,
  902.                                 text,
  903.                                 image, imageSel,
  904.                                 new OPJMarkerData(wxT("INFO"))
  905.                                 );
  906.  
  907.                         text = wxT("");
  908.                         if (scod & 0x02)
  909.                                 text << wxT("Possible SOPs");
  910.                         else
  911.                                 text << wxT("No SOPs");
  912.  
  913.                         if (scod & 0x04)
  914.                                 text << wxT(", possible EPHs");
  915.                         else
  916.                                 text << wxT(", no EPHs");
  917.  
  918.                         subcurrid3 = m_tree->AppendItem(currid,
  919.                                 text,
  920.                                 image, imageSel,
  921.                                 new OPJMarkerData(wxT("INFO"))
  922.                                 );
  923.  
  924.                         if (m_file->Read(onebyte, 1) != 1)
  925.                                 break;
  926.                         unsigned char progord = onebyte[0];
  927.  
  928.                         if (m_file->Read(twobytes, 2) != 2)
  929.                                 break;
  930.                         unsigned short int numlayers = STREAM_TO_UINT16(twobytes, 0);
  931.  
  932.                         if (m_file->Read(onebyte, 1) != 1)
  933.                                 break;
  934.                         unsigned char mctransform = onebyte[0];
  935.  
  936.                         if (m_file->Read(onebyte, 1) != 1)
  937.                                 break;
  938.                         unsigned char decomplevs = onebyte[0];
  939.  
  940.                         if (m_file->Read(onebyte, 1) != 1)
  941.                                 break;
  942.                         unsigned char cbswidth = onebyte[0];
  943.  
  944.                         if (m_file->Read(onebyte, 1) != 1)
  945.                                 break;
  946.                         unsigned char cbsheight = onebyte[0];
  947.  
  948.                         if (m_file->Read(onebyte, 1) != 1)
  949.                                 break;
  950.                         unsigned char cbstyle = onebyte[0];
  951.  
  952.                         if (m_file->Read(onebyte, 1) != 1)
  953.                                 break;
  954.                         unsigned char transform = onebyte[0];
  955.  
  956.                         subcurrid3 = m_tree->AppendItem(currid,
  957.                                 wxString::Format(wxT("%d levels (%d resolutions)"), decomplevs, decomplevs + 1),
  958.                                 image, imageSel,
  959.                                 new OPJMarkerData(wxT("INFO"))
  960.                                 );
  961.  
  962.                         text = wxT("");
  963.                         switch (progord) {
  964.                         case (0):
  965.                                 text << wxT("LRCP");
  966.                                 break;
  967.                         case (1):
  968.                                 text << wxT("RLCP");
  969.                                 break;
  970.                         case (2):
  971.                                 text << wxT("LRCP");
  972.                                 break;
  973.                         case (3):
  974.                                 text << wxT("RPCL");
  975.                                 break;
  976.                         case (4):
  977.                                 text << wxT("CPRL");
  978.                                 break;
  979.                         default:
  980.                                 text << wxT("unknown progression");
  981.                                 break;
  982.                         }
  983.                         text << wxString::Format(wxT(", %d layers"), numlayers);
  984.                         if (transform & 0x01)
  985.                                 text << wxT(", 5-3 rev.");
  986.                         else
  987.                                 text << wxT(", 9-7 irr.");
  988.                         subcurrid3 = m_tree->AppendItem(currid,
  989.                                 text,
  990.                                 image, imageSel,
  991.                                 new OPJMarkerData(wxT("INFO"))
  992.                                 );
  993.  
  994.                         subcurrid3 = m_tree->AppendItem(currid,
  995.                                 wxString::Format(wxT("Code-blocks: %dx%d"), 1 << ((cbswidth & 0x0F) + 2), 1 << ((cbsheight & 0x0F) + 2)),
  996.                                 image, imageSel,
  997.                                 new OPJMarkerData(wxT("INFO"))
  998.                                 );
  999.  
  1000.                         switch (mctransform) {
  1001.                         case (0):
  1002.                                 {
  1003.                                 text = wxT("No MCT");
  1004.                                 }
  1005.                                 break;
  1006.                         case (1):
  1007.                                 {
  1008.                                 text = wxT("Reversible MCT on 0, 1, 2");
  1009.                                 }
  1010.                                 break;
  1011.                         case (2):
  1012.                                 {
  1013.                                 text = wxT("Irreversible MCT on 0, 1, 2");
  1014.                                 }
  1015.                                 break;
  1016.                         default:
  1017.                                 {
  1018.                                 text = wxT("Unknown");
  1019.                                 }
  1020.                                 break;
  1021.                         };
  1022.                         subcurrid3 = m_tree->AppendItem(currid,
  1023.                                 text,
  1024.                                 image, imageSel,
  1025.                                 new OPJMarkerData(wxT("INFO"))
  1026.                                 );
  1027.  
  1028.  
  1029.                         image = m_tree->TreeCtrlIcon_Folder;
  1030.                         imageSel = image + 1;
  1031.  
  1032.                         subcurrid3 = m_tree->AppendItem(currid,
  1033.                                 wxT("Coding styles"),
  1034.                                 image, imageSel,
  1035.                                 new OPJMarkerData(wxT("INFO"))
  1036.                                 );
  1037.  
  1038.                         image = m_tree->TreeCtrlIcon_File;
  1039.                         imageSel = image + 1;
  1040.  
  1041.                         if (cbstyle & 0x01)
  1042.                                 text = wxT("Selective arithmetic coding bypass");
  1043.                         else
  1044.                                 text = wxT("No selective arithmetic coding bypass");
  1045.                         wxTreeItemId subcurrid4 = m_tree->AppendItem(subcurrid3,
  1046.                                 text,
  1047.                                 image, imageSel,
  1048.                                 new OPJMarkerData(wxT("INFO"))
  1049.                                 );
  1050.  
  1051.                         if (cbstyle & 0x02)
  1052.                                 text = wxT("Reset context probabilities on coding pass boundaries");
  1053.                         else
  1054.                                 text = wxT("No reset of context probabilities on coding pass boundaries");
  1055.                         subcurrid4 = m_tree->AppendItem(subcurrid3,
  1056.                                 text,
  1057.                                 image, imageSel,
  1058.                                 new OPJMarkerData(wxT("INFO"))
  1059.                                 );
  1060.  
  1061.                         if (cbstyle & 0x04)
  1062.                                 text = wxT("Termination on each coding passs");
  1063.                         else
  1064.                                 text = wxT("No termination on each coding pass");
  1065.                         subcurrid4 = m_tree->AppendItem(subcurrid3,
  1066.                                 text,
  1067.                                 image, imageSel,
  1068.                                 new OPJMarkerData(wxT("INFO"))
  1069.                                 );
  1070.  
  1071.                         if (cbstyle & 0x08)
  1072.                                 text = wxT("Vertically stripe causal context");
  1073.                         else
  1074.                                 text = wxT("No vertically stripe causal context");
  1075.                         subcurrid4 = m_tree->AppendItem(subcurrid3,
  1076.                                 text,
  1077.                                 image, imageSel,
  1078.                                 new OPJMarkerData(wxT("INFO"))
  1079.                                 );
  1080.  
  1081.                         if (cbstyle & 0x10)
  1082.                                 text = wxT("Predictable termination");
  1083.                         else
  1084.                                 text = wxT("No predictable termination");
  1085.                         subcurrid4 = m_tree->AppendItem(subcurrid3,
  1086.                                 text,
  1087.                                 image, imageSel,
  1088.                                 new OPJMarkerData(wxT("INFO"))
  1089.                                 );
  1090.  
  1091.                         if (cbstyle & 0x20)
  1092.                                 text = wxT("Segmentation symbols are used");
  1093.                         else
  1094.                                 text = wxT("No segmentation symbols are used");
  1095.                         subcurrid4 = m_tree->AppendItem(subcurrid3,
  1096.                                 text,
  1097.                                 image, imageSel,
  1098.                                 new OPJMarkerData(wxT("INFO"))
  1099.                                 );
  1100.  
  1101.                         };
  1102.                         break;
  1103.  
  1104.                 /////////
  1105.                 // QCC //
  1106.                 /////////
  1107.                 case QCC_VAL:
  1108.                         {
  1109.                         unsigned short int cqcc;
  1110.                         if (csiz < 257) {
  1111.                                 if (m_file->Read(onebyte, 1) != 1)
  1112.                                         break;
  1113.                                 cqcc = onebyte[0];
  1114.                         } else {
  1115.                                 if (m_file->Read(twobytes, 2) != 2)
  1116.                                         break;
  1117.                                 cqcc = STREAM_TO_UINT16(twobytes, 0);
  1118.                         }
  1119.  
  1120.                         wxTreeItemId subcurrid = m_tree->AppendItem(currid,
  1121.                                 wxString::Format(wxT("Comp. no. %d"), cqcc),
  1122.                                 image, imageSel,
  1123.                                 new OPJMarkerData(wxT("INFO"))
  1124.                                 );
  1125.                        
  1126.                         if (m_file->Read(onebyte, 1) != 1)
  1127.                                 break;
  1128.                         unsigned char sqcc = onebyte[0];
  1129.  
  1130.                         wxString text;
  1131.                         switch (sqcc & 0x1F) {
  1132.                         case (0):
  1133.                                 text = wxT("No quantization");
  1134.                                 break;
  1135.                         case (1):
  1136.                                 text = wxT("Scalar implicit");
  1137.                                 break;
  1138.                         case (2):
  1139.                                 text = wxT("Scalar explicit");
  1140.                                 break;
  1141.                         default:
  1142.                                 text = wxT("Unknown");
  1143.                                 break;
  1144.                         }
  1145.                         text << wxString::Format(wxT(", %d guard bits"), (sqcc & 0xE0) >> 5);
  1146.                         wxTreeItemId subcurrid3 = m_tree->AppendItem(currid,
  1147.                                 text,
  1148.                                 image, imageSel,
  1149.                                 new OPJMarkerData(wxT("INFO"))
  1150.                                 );
  1151.  
  1152.                         }
  1153.                         break;
  1154.  
  1155.                 /////////
  1156.                 // QCD //
  1157.                 /////////
  1158.                 case QCD_VAL:
  1159.                         {
  1160.                         if (m_file->Read(onebyte, 1) != 1)
  1161.                                 break;
  1162.                         unsigned char sqcd = onebyte[0];
  1163.  
  1164.                         wxString text;
  1165.                         switch (sqcd & 0x1F) {
  1166.                         case (0):
  1167.                                 text = wxT("No quantization");
  1168.                                 break;
  1169.                         case (1):
  1170.                                 text = wxT("Scalar implicit");
  1171.                                 break;
  1172.                         case (2):
  1173.                                 text = wxT("Scalar explicit");
  1174.                                 break;
  1175.                         default:
  1176.                                 text = wxT("Unknown");
  1177.                                 break;
  1178.                         }
  1179.                         text << wxString::Format(wxT(", %d guard bits"), (sqcd & 0xE0) >> 5);
  1180.                         wxTreeItemId subcurrid3 = m_tree->AppendItem(currid,
  1181.                                 text,
  1182.                                 image, imageSel,
  1183.                                 new OPJMarkerData(wxT("INFO"))
  1184.                                 );
  1185.  
  1186.                         };
  1187.                         break;
  1188.  
  1189.                 /////////
  1190.                 // COM //
  1191.                 /////////
  1192.                 case COM_VAL:
  1193.                         {
  1194.                         #define showlen 25
  1195.                         char comment[showlen];
  1196.                         wxString comments;
  1197.  
  1198.                         if (m_file->Read(twobytes, 2) != 2)
  1199.                                 break;
  1200.                         unsigned short int rcom = STREAM_TO_UINT16(twobytes, 0);
  1201.  
  1202.                         wxString text;
  1203.                         if (rcom == 0)
  1204.                                 text = wxT("Binary values");
  1205.                         else if (rcom == 1)
  1206.                                 text = wxT("ISO 8859-1 (latin-1) values");
  1207.                         else if (rcom < 65535)
  1208.                                 text = wxT("Reserved for registration");
  1209.                         else
  1210.                                 text = wxT("Reserved for extension");
  1211.                         wxTreeItemId subcurrid3 = m_tree->AppendItem(currid,
  1212.                                 text,
  1213.                                 image, imageSel,
  1214.                                 new OPJMarkerData(wxT("INFO"))
  1215.                                 );
  1216.  
  1217.                         if (m_file->Read(comment, showlen) != showlen)
  1218.                                 break;
  1219.                         comments = wxString::FromAscii(comment).Truncate(wxMin(showlen, currlen - 4));
  1220.                         if ((currlen - 4) > showlen)
  1221.                                 comments << wxT("...");
  1222.                         subcurrid3 = m_tree->AppendItem(currid,
  1223.                                 comments,
  1224.                                 image, imageSel,
  1225.                                 new OPJMarkerData(wxT("INFO"))
  1226.                                 );
  1227.                         };
  1228.                         break;
  1229.  
  1230.                 /////////
  1231.                 // TLM //
  1232.                 /////////
  1233.                 case TLM_VAL:
  1234.                         {
  1235.                         if (m_file->Read(onebyte, 1) != 1)
  1236.                                 break;
  1237.                         unsigned char ztlm = onebyte[0];
  1238.  
  1239.                         if (m_file->Read(onebyte, 1) != 1)
  1240.                                 break;
  1241.                         unsigned char stlm = onebyte[0];
  1242.  
  1243.                         image = m_tree->TreeCtrlIcon_File;
  1244.                         imageSel = image + 1;
  1245.  
  1246.                         wxTreeItemId subcurrid3 = m_tree->AppendItem(currid,
  1247.                                 wxString::Format(wxT("TLM #%d"), ztlm),
  1248.                                 image, imageSel,
  1249.                                 new OPJMarkerData(wxT("INFO"))
  1250.                                 );
  1251.  
  1252.                         subcurrid3 = m_tree->AppendItem(currid,
  1253.                                 wxString::Format(wxT("%d bits/index, %d bits/length"),
  1254.                                 8 * ((stlm & 0x30) >> 4), 16 + 16 * ((stlm & 0x40) >> 6)),
  1255.                                 image, imageSel,
  1256.                                 new OPJMarkerData(wxT("INFO"))
  1257.                                 );
  1258.  
  1259.                         int n, numparts;
  1260.  
  1261.                         numparts = (currlen - 2) / ( ((stlm & 0x30) >> 4) + 2 + 2 * ((stlm & 0x40) >> 6));
  1262.  
  1263.                         image = m_tree->TreeCtrlIcon_Folder;
  1264.                         imageSel = image + 1;
  1265.  
  1266.                         subcurrid3 = m_tree->AppendItem(currid,
  1267.                                 wxT("Tile parts"),
  1268.                                 image, imageSel,
  1269.                                 new OPJMarkerData(wxT("INFO"))
  1270.                                 );
  1271.  
  1272.                         image = m_tree->TreeCtrlIcon_File;
  1273.                         imageSel = image + 1;
  1274.  
  1275.                         for (n = 0; n < numparts; n++) {
  1276.  
  1277.                                 unsigned short int ttlm;
  1278.                                 unsigned long int ptlm;
  1279.  
  1280.                                 switch (((stlm & 0x30) >> 4)) {
  1281.  
  1282.                                 case 0:
  1283.                                         ttlm = 0;
  1284.                                         break;
  1285.  
  1286.                                 case 1:
  1287.                                         if (m_file->Read(onebyte, 1) != 1)
  1288.                                                 break;
  1289.                                         ttlm = onebyte[0];
  1290.                                         break;
  1291.  
  1292.                                 case 2:
  1293.                                         if (m_file->Read(twobytes, 2) != 2)
  1294.                                                 break;
  1295.                                         ttlm = STREAM_TO_UINT16(twobytes, 0);
  1296.                                         break;
  1297.  
  1298.                                 }
  1299.  
  1300.                                 switch (((stlm & 0x40) >> 6)) {
  1301.  
  1302.                                 case 0:
  1303.                                         if (m_file->Read(twobytes, 2) != 2)
  1304.                                                 break;
  1305.                                         ptlm = STREAM_TO_UINT16(twobytes, 0);
  1306.                                         break;
  1307.  
  1308.                                 case 1:
  1309.                                         if (m_file->Read(fourbytes, 4) != 4)
  1310.                                                 break;
  1311.                                         ptlm = STREAM_TO_UINT32(fourbytes, 0);
  1312.                                         break;
  1313.  
  1314.                                 }
  1315.  
  1316.                                 wxTreeItemId subcurrid4 = m_tree->AppendItem(subcurrid3,
  1317.                                         wxString::Format(wxT("Tile %d: %d bytes"), ttlm, ptlm),
  1318.                                         image, imageSel,
  1319.                                         new OPJMarkerData(wxT("INFO"))
  1320.                                         );
  1321.  
  1322.                         }
  1323.  
  1324.                         }
  1325.                         break;
  1326.  
  1327.                 /////////
  1328.                 // POD //
  1329.                 /////////
  1330.                 case POD_VAL:
  1331.                         {
  1332.                         int n, numchanges;
  1333.  
  1334.                         if (csiz < 257)
  1335.                                 numchanges = (currlen - 2) / 7;
  1336.                         else
  1337.                                 numchanges = (currlen - 2) / 9;
  1338.  
  1339.                         for (n = 0; n < numchanges; n++) {
  1340.  
  1341.                                 image = m_tree->TreeCtrlIcon_Folder;
  1342.                                 imageSel = image + 1;
  1343.  
  1344.                                 wxTreeItemId subcurrid3 = m_tree->AppendItem(currid,
  1345.                                         wxString::Format(wxT("Change #%d"), n),
  1346.                                         image, imageSel,
  1347.                                         new OPJMarkerData(wxT("INFO"))
  1348.                                         );
  1349.  
  1350.                                 if (m_file->Read(onebyte, 1) != 1)
  1351.                                         break;
  1352.                                 unsigned char rspod = onebyte[0];
  1353.  
  1354.                                 unsigned short int cspod;
  1355.                                 if (csiz < 257) {
  1356.                                         if (m_file->Read(onebyte, 1) != 1)
  1357.                                                 break;
  1358.                                         cspod = onebyte[0];
  1359.                                 } else {
  1360.                                         if (m_file->Read(twobytes, 2) != 2)
  1361.                                                 break;
  1362.                                         cspod = STREAM_TO_UINT16(twobytes, 0);
  1363.                                 }
  1364.  
  1365.                                 if (m_file->Read(twobytes, 2) != 2)
  1366.                                         break;
  1367.                                 unsigned short int lyepod = STREAM_TO_UINT16(twobytes, 0);
  1368.  
  1369.                                 if (m_file->Read(onebyte, 1) != 1)
  1370.                                         break;
  1371.                                 unsigned char repod = onebyte[0];
  1372.  
  1373.                                 unsigned short int cepod;
  1374.                                 if (csiz < 257) {
  1375.                                         if (m_file->Read(onebyte, 1) != 1)
  1376.                                                 break;
  1377.                                         cepod = onebyte[0];
  1378.                                 } else {
  1379.                                         if (m_file->Read(twobytes, 2) != 2)
  1380.                                                 break;
  1381.                                         cepod = STREAM_TO_UINT16(twobytes, 0);
  1382.                                 }
  1383.  
  1384.                                 if (m_file->Read(onebyte, 1) != 1)
  1385.                                         break;
  1386.                                 unsigned char ppod = onebyte[0];
  1387.  
  1388.                                 image = m_tree->TreeCtrlIcon_File;
  1389.                                 imageSel = image + 1;
  1390.  
  1391.                                 wxTreeItemId subcurrid4 = m_tree->AppendItem(subcurrid3,
  1392.                                         wxString::Format(wxT("%d <= Resolution < %d"), rspod, repod),
  1393.                                         image, imageSel,
  1394.                                         new OPJMarkerData(wxT("INFO"))
  1395.                                         );
  1396.  
  1397.                                 subcurrid4 = m_tree->AppendItem(subcurrid3,
  1398.                                         wxString::Format(wxT("%d <= Component < %d"), cspod, cepod),
  1399.                                         image, imageSel,
  1400.                                         new OPJMarkerData(wxT("INFO"))
  1401.                                         );
  1402.  
  1403.                                 subcurrid4 = m_tree->AppendItem(subcurrid3,
  1404.                                         wxString::Format(wxT("0 <= Layer < %d"), lyepod),
  1405.                                         image, imageSel,
  1406.                                         new OPJMarkerData(wxT("INFO"))
  1407.                                         );
  1408.  
  1409.                                 wxString text = wxT("");
  1410.                                 switch (ppod) {
  1411.                                 case (0):
  1412.                                         text << wxT("LRCP");
  1413.                                         break;
  1414.                                 case (1):
  1415.                                         text << wxT("RLCP");
  1416.                                         break;
  1417.                                 case (2):
  1418.                                         text << wxT("LRCP");
  1419.                                         break;
  1420.                                 case (3):
  1421.                                         text << wxT("RPCL");
  1422.                                         break;
  1423.                                 case (4):
  1424.                                         text << wxT("CPRL");
  1425.                                         break;
  1426.                                 default:
  1427.                                         text << wxT("unknown progression");
  1428.                                         break;
  1429.                                 }
  1430.                                 subcurrid4 = m_tree->AppendItem(subcurrid3,
  1431.                                         text,
  1432.                                         image, imageSel,
  1433.                                         new OPJMarkerData(wxT("INFO"))
  1434.                                         );
  1435.                         }
  1436.  
  1437.                         }
  1438.                         break;
  1439.  
  1440.                 /////////
  1441.                 // SOD //
  1442.                 /////////
  1443.                 case SOD_VAL:
  1444.                         {
  1445.                         inside_sod = 1;
  1446.                         };
  1447.                         break;
  1448.  
  1449.                 default:
  1450.                         break;
  1451.                        
  1452.                 }
  1453.                                                                
  1454.                 // increment number of markers
  1455.                 if (nmarks++ >= maxmarks) {
  1456.                         WriteText(wxT("Maximum amount of markers exceeded"));
  1457.                         break;
  1458.                 }
  1459.  
  1460.                 // advance position
  1461.                 OPJ_ADVANCE(currlen + 2);
  1462.         }      
  1463.  
  1464.         WriteText(wxT("Search finished"));
  1465. }
  1466.