338 lines
9.9 KiB
C++
338 lines
9.9 KiB
C++
/*
|
|
* Copyright (c) 2007, Digital Signal Processing Laboratory, Università degli studi di Perugia (UPG), Italy
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
|
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
* POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
#include "OPJViewer.h"
|
|
|
|
/* From little endian to big endian, 2 bytes */
|
|
#define BYTE_SWAP2(X) ((X & 0x00FF) << 8) | ((X & 0xFF00) >> 8)
|
|
#define BYTE_SWAP4(X) ((X & 0x000000FF) << 24) | ((X & 0x0000FF00) << 8) | ((X & 0x00FF0000) >> 8) | ((X & 0xFF000000) >> 24)
|
|
|
|
/* From codestream to int values */
|
|
#define STREAM_TO_UINT32(C, P) (((unsigned long int) (C)[(P) + 0] << 24) + \
|
|
((unsigned long int) (C)[(P) + 1] << 16) + \
|
|
((unsigned long int) (C)[(P) + 2] << 8) + \
|
|
((unsigned long int) (C)[(P) + 3] << 0))
|
|
|
|
#define STREAM_TO_UINT16(C, P) (((unsigned long int) (C)[(P) + 0] << 8) + \
|
|
((unsigned long int) (C)[(P) + 1] << 0))
|
|
|
|
|
|
/* Markers values */
|
|
enum {
|
|
SOC_VAL = 0xFF4F,
|
|
SOT_VAL = 0xFF90,
|
|
SOD_VAL = 0xFF93,
|
|
EOC_VAL = 0xFFD9,
|
|
SIZ_VAL = 0xFF51,
|
|
COD_VAL = 0xFF52,
|
|
COC_VAL = 0xFF53,
|
|
RGN_VAL = 0xFF5E,
|
|
QCD_VAL = 0xFF5C,
|
|
QCC_VAL = 0xFF5D,
|
|
POD_VAL = 0xFF5F,
|
|
TLM_VAL = 0xFF55,
|
|
PLM_VAL = 0xFF57,
|
|
PLT_VAL = 0xFF58,
|
|
PPM_VAL = 0xFF60,
|
|
PPT_VAL = 0xFF61,
|
|
SOP_VAL = 0xFF91,
|
|
EPH_VAL = 0xFF92,
|
|
CME_VAL = 0xFF64,
|
|
#ifndef USEOLDJPWL
|
|
EPB_VAL = 0xFF66,
|
|
ESD_VAL = 0xFF67,
|
|
EPC_VAL = 0xFF68,
|
|
RED_VAL = 0xFF69
|
|
#else
|
|
EPB_VAL = 0xFF96,
|
|
ESD_VAL = 0xFF98,
|
|
EPC_VAL = 0xFF97,
|
|
RED_VAL = 0xFF99
|
|
#endif
|
|
};
|
|
|
|
// All the markers in one vector
|
|
unsigned short int marker_val[] = {
|
|
SOC_VAL, SOT_VAL, SOD_VAL, EOC_VAL,
|
|
SIZ_VAL,
|
|
COD_VAL, COC_VAL, RGN_VAL, QCD_VAL, QCC_VAL, POD_VAL,
|
|
TLM_VAL, PLM_VAL, PLT_VAL, PPM_VAL, PPT_VAL,
|
|
SOP_VAL, EPH_VAL,
|
|
CME_VAL,
|
|
EPB_VAL, ESD_VAL, EPC_VAL, RED_VAL
|
|
};
|
|
|
|
// Marker names
|
|
char *marker_name[] = {
|
|
"SOC", "SOT", "SOD", "EOC",
|
|
"SIZ",
|
|
"COD", "COC", "RGN", "QCD", "QCC", "POD",
|
|
"TLM", "PLM", "PLT", "PPM", "PPT",
|
|
"SOP", "EPH",
|
|
"CME",
|
|
"EPB", "ESD", "EPC", "RED"
|
|
};
|
|
|
|
// Marker descriptions
|
|
char *marker_descr[] = {
|
|
"Start of codestream", "Start of tile-part", "Start of data", "End of codestream",
|
|
"Image and tile size",
|
|
"Coding style default", "Coding style component", "Region-of-interest", "Quantization default",
|
|
"Quantization component", "Progression order change, default",
|
|
"Tile-part lengths, main header", "Packet length, main header", "Packets length, tile-part header",
|
|
"Packed packet headers, main header", "Packed packet headers, tile-part header",
|
|
"Start of packet", "End of packet header",
|
|
"Comment and extension",
|
|
"Error Protection Block", "Error Sensitivity Descriptor", "Error Protection Capability",
|
|
"Residual Errors Descriptor"
|
|
};
|
|
|
|
void OPJParseThread::ParseJ2KFile(wxFile *m_file, wxFileOffset offset, wxFileOffset length, wxTreeItemId parentid)
|
|
{
|
|
// check if the file is opened
|
|
if (m_file->IsOpened())
|
|
WriteText(wxT("File OK"));
|
|
else
|
|
return;
|
|
|
|
// position at the beginning
|
|
m_file->Seek(offset, wxFromStart);
|
|
|
|
//WriteText(wxString::Format(wxT("from to %d"), length));
|
|
|
|
// navigate the file
|
|
int m, inside_sod = 0, nmarks = 0, maxmarks = 10000, done = 0;
|
|
unsigned char onebyte[1];
|
|
unsigned char twobytes[2];
|
|
unsigned char fourbytes[4];
|
|
unsigned short int currmark;
|
|
unsigned short int currlen;
|
|
int lastPsot = 0, lastsotpos = 0;
|
|
|
|
WriteText(wxT("Start search..."));
|
|
while ((offset < length) && (!m_file->Eof())) {
|
|
|
|
done = 0;
|
|
|
|
// read da marka
|
|
if (m_file->Read(twobytes, 2) != 2)
|
|
break;
|
|
currmark = (((unsigned short int) twobytes[0]) << 8) + (unsigned short int) twobytes[1];
|
|
|
|
// Markers cycle
|
|
for (m = 0; m < 23; m++) {
|
|
|
|
// check the marker
|
|
if (currmark == marker_val[m]) {
|
|
|
|
if (currmark == SOD_VAL) {
|
|
|
|
// we enter SOD
|
|
currlen = 0;
|
|
inside_sod = 1;
|
|
|
|
} else if ((currmark == SOC_VAL) || (currmark == EOC_VAL) || (currmark == EPH_VAL))
|
|
|
|
currlen = 0;
|
|
|
|
else {
|
|
|
|
// read length
|
|
if (m_file->Read(twobytes, 2) != 2)
|
|
break;
|
|
currlen = (((unsigned short int) twobytes[0]) << 8) + (unsigned short int) twobytes[1];
|
|
|
|
}
|
|
|
|
// inside SOD, only some markers are allowed
|
|
if (inside_sod && (currmark != SOD_VAL) && (currmark != SOT_VAL)
|
|
&& (currmark != EOC_VAL) && (currmark != SOP_VAL) && (currmark != EPH_VAL))
|
|
break; /*randomly marker coincident data */
|
|
|
|
if (inside_sod && (currmark == SOT_VAL) && (lastPsot == 0))
|
|
inside_sod = 0; /* random data coincident with SOT, but last SOT was the last one */
|
|
|
|
if (inside_sod && (currmark == SOT_VAL))
|
|
inside_sod = 0; /* new tile part */
|
|
|
|
// here we pass to AppendItem() normal and selected item images (we
|
|
// suppose that selected image follows the normal one in the enum)
|
|
int image, imageSel;
|
|
image = m_tree->TreeCtrlIcon_Folder;
|
|
imageSel = image + 1;
|
|
|
|
// append the marker
|
|
wxTreeItemId currid = m_tree->AppendItem(parentid,
|
|
wxString::Format(wxT("%03d: %s (0x%04X)"), nmarks, marker_name[m], marker_val[m]),
|
|
image, imageSel,
|
|
new OPJMarkerData(wxT("MARK"), m_tree->m_fname.GetFullPath(), offset, offset + currlen + 1)
|
|
);
|
|
|
|
// append some info
|
|
image = m_tree->TreeCtrlIcon_File;
|
|
imageSel = image + 1;
|
|
|
|
// marker name
|
|
wxTreeItemId subcurrid1 = m_tree->AppendItem(currid,
|
|
wxT("*** ") + wxString(marker_descr[m]) + wxT(" ***"),
|
|
image, imageSel,
|
|
new OPJMarkerData(wxT("INFO"))
|
|
);
|
|
m_tree->SetItemFont(subcurrid1, *wxITALIC_FONT);
|
|
|
|
// position and length
|
|
wxTreeItemId subcurrid2 = m_tree->AppendItem(currid,
|
|
wxLongLong(offset).ToString() + wxT(" > ") + wxLongLong(offset + currlen + 1).ToString() +
|
|
wxT(", ") + wxString::Format(wxT("%d + 2 (%d)"), currlen, currlen + 2),
|
|
image, imageSel,
|
|
new OPJMarkerData(wxT("INFO"))
|
|
);
|
|
|
|
// give additional info on markers
|
|
switch (currmark) {
|
|
|
|
case SOP_VAL:
|
|
{
|
|
// read packet number
|
|
if (m_file->Read(twobytes, 2) != 2)
|
|
break;
|
|
int packnum = STREAM_TO_UINT16(twobytes, 0);;
|
|
wxTreeItemId subcurrid3 = m_tree->AppendItem(currid,
|
|
wxString::Format(wxT("Pack. no. %d"), packnum),
|
|
image, imageSel,
|
|
new OPJMarkerData(wxT("INFO"))
|
|
);
|
|
}
|
|
break;
|
|
|
|
case SIZ_VAL:
|
|
{
|
|
m_file->Seek(2, wxFromCurrent);
|
|
if (m_file->Read(fourbytes, 4) != 4)
|
|
break;
|
|
unsigned long int xsiz = STREAM_TO_UINT32(fourbytes, 0);
|
|
|
|
if (m_file->Read(fourbytes, 4) != 4)
|
|
break;
|
|
unsigned long int ysiz = STREAM_TO_UINT32(fourbytes, 0);
|
|
|
|
m_file->Seek(24, wxFromCurrent);
|
|
if (m_file->Read(twobytes, 2) != 2)
|
|
break;
|
|
unsigned short int csiz = STREAM_TO_UINT16(twobytes, 0);
|
|
|
|
if (m_file->Read(onebyte, 1) != 1)
|
|
break;
|
|
unsigned char ssiz = onebyte[0];
|
|
|
|
wxTreeItemId subcurrid3 = m_tree->AppendItem(currid,
|
|
wxString::Format(wxT("%d x %d, %d comps. @ %d bpp"), xsiz, ysiz, csiz, (ssiz + 1) & 0xEF),
|
|
image, imageSel,
|
|
new OPJMarkerData(wxT("INFO"))
|
|
);
|
|
|
|
}
|
|
break;
|
|
|
|
case SOT_VAL:
|
|
{
|
|
if (m_file->Read(twobytes, 2) != 2)
|
|
break;
|
|
unsigned short int isot = STREAM_TO_UINT16(twobytes, 0);
|
|
|
|
if (m_file->Read(fourbytes, 4) != 4)
|
|
break;
|
|
unsigned long int psot = STREAM_TO_UINT32(fourbytes, 0);
|
|
|
|
if (m_file->Read(onebyte, 1) != 1)
|
|
break;
|
|
unsigned char tpsot = onebyte[0];
|
|
|
|
if (m_file->Read(onebyte, 1) != 1)
|
|
break;
|
|
unsigned char tnsot = onebyte[0];
|
|
|
|
wxTreeItemId subcurrid3 = m_tree->AppendItem(currid,
|
|
wxString::Format(wxT("tile %d, psot = %d, part %d of %d"), isot, psot, tpsot, tnsot),
|
|
image, imageSel,
|
|
new OPJMarkerData(wxT("INFO"))
|
|
);
|
|
|
|
lastPsot = psot;
|
|
lastsotpos = offset;
|
|
};
|
|
break;
|
|
|
|
case CME_VAL:
|
|
{
|
|
#define showlen 25
|
|
unsigned char comment[showlen];
|
|
|
|
m_file->Seek(2, wxFromCurrent);
|
|
if (m_file->Read(comment, showlen) != showlen)
|
|
break;
|
|
|
|
wxTreeItemId subcurrid3 = m_tree->AppendItem(currid,
|
|
wxString::Format(wxT("%.*s%s"), wxMin(showlen, currlen - 4), comment,
|
|
(((currlen - 4) > showlen) ? "..." : "")),
|
|
image, imageSel,
|
|
new OPJMarkerData(wxT("INFO"))
|
|
);
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
|
|
// increment number of markers
|
|
nmarks++;
|
|
if (nmarks >= maxmarks)
|
|
break;
|
|
|
|
// increment offset
|
|
if (currmark == SOD_VAL)
|
|
offset += lastPsot - (offset - lastsotpos);
|
|
else
|
|
offset += (2 + currlen);
|
|
|
|
m_file->Seek(offset, wxFromStart);
|
|
done = 1;
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (done)
|
|
continue;
|
|
else {
|
|
offset++;
|
|
m_file->Seek(offset, wxFromStart);
|
|
}
|
|
}
|
|
|
|
}
|