You have forgotten to mention the version of the library.
Neither 'jp2_read_xml()' nor 'jp2_write_xml()' are implemented yet
in version 1 and version 2.
At the bottom I have appended some text excerpted from the spec
'ISO/IEC 15444-1 : 2002'.
In short: XML boxes can be (nearly) everywhere.
What do you want to do with the data after having read it?
How do you want to feed in the data for writing?
winfried
-------------------
ISO/IEC 15444-1 : 2002
openjpeg functions:
JP2 file
JPEG 2000 Signature box (I.5.1) jp2_read_jp()
File Type box (I.5.2) jp2_read_ftyp()
JP2 Header box (superbox) (I.5.3) jp2_read_jp2h()
Image Header box (I.5.3.1) jp2_read_ihdr()
Bits Per Component box (I.5.3.2) jp2_read_bpcc()
Colour Specification box 0 (I.5.3.3) jp2_read_colr()
...
Colour Specification box n-1 (I.5.3.3)
Palette box (I.5.3.4) jp2_read_pclr()
Component Mapping box (I.5.3.5) jp2_read_cmap()
Channel Definition box (I.5.3.6) jp2_read_cdef()
Resolution box (superbox) (I.5.3.7)
Capture Resolution box (I.5.3.7.1)
Default Display Resolution box (I.5.3.7.2)
Contiguous Codestream box (I.5.4) 0 jp2_read_jp2c()
...
Contiguous Codestream box (I.5.4) m1 jp2_read_jp2c()
IPR box (I.6)
XML boxes (I.7.1)
UUID boxes (I.7.2)
UUID Info boxes (superbox) (I.7.3)
UUID List box (I.7.3.1)
Data Entry URL box (I.7.3.2)
Figure I-1 -- Conceptual structure of a JP2 file
As shown in Figure I-1, a JP2 file contains a JPEG 2000 Signature
box, JP2 Header box, and one or more Contiguous Codestream boxes.
A JP2 file may also contain other boxes as determined by the file
writer. For example, a JP2 file may contain several XML boxes
(containing metadata) between the JP2 Header box and the first
Contiguous Codestream box.
I.7.1 XML boxes
An XML box contains vendor specific information (in XML format)
other than the information contained within boxes
defined by this Recommendation | International Standard.
There may be multiple XML boxes within the file, and those
boxes may be found anywhere in the file except before the
File Type ('ftyp') box.
The type of an XML box is 'xml ' (0x786D6C20). The contents of
the box shall be as follows:
DATA
Figure I-18 -- Organization of the contents of the XML box
DATA:This field shall contain a well-formed XML document as
defined by REC-xml-19980210.
The existence of any XML boxes is optional for conforming
files. Also, any XML box shall not contain any information
necessary for decoding the image to the extent that is defined
within this part of this Recommendation | International
Standard, and the correct interpretation of the contents of
any XML box shall not change the visual appearance of the
image. All readers may ignore any XML box in the file.
-- Kaori Hagihara U.C.Louvain EPL Bâtiment Stévin; Place du Levant, 2; B-1348 Louvain-la-Neuve Belgium Tel. +32 (0)10/47.23.00; Fax. +32 (0)10/47.20.89
>>How do you want to feed in the data for writing?
>
>format the data and then write it within a XML box (this is what I
>have to investigate now looking the code of the openJPEG)
Your answer is not just what I expected.
So I suppose:
You want to tailor the library to meet your needs.
Your xml data are collected in a list of type:
XML_DATA_COLLECTOR.data
.len
.next
In 'jp2.h' you have to add:
#define JP2_XML 0x786D6C20 /**< XML box */
In 'jp2.c' you could add:
static void jp2_write_xml(opj_cio_t *cio, XML_DATA_COLLECTOR) {
unsigned int i;
opj_jp2_box_t box;
box.init_pos = cio_tell(cio);
cio_skip(cio, 4);
cio_write(cio, JP2_XML, 4); /* box type is 'xml ' */
for (i = 0; i < XML_DATA_COLLECTOR.len; i++) {
cio_write(cio, XML_DATA_COLLECTOR.data[i], 1);
}
box.length = cio_tell(cio) - box.init_pos;
cio_seek(cio, box.init_pos);
cio_write(cio, box.length, 4); /* L */
cio_seek(cio, box.init_pos + box.length);
}
static opj_bool jp2_read_xml(opj_jp2_t *jp2, opj_cio_t *cio,
opj_jp2_box_t *box, XML_DATA_COLLECTOR)
{
unsigned char *buf;
int len;
opj_common_ptr cinfo;
cinfo = jp2->cinfo;
len = box->init_pos + box->length - cio_tell(cio);
if (len < 0)
{
opj_event_msg(cinfo, EVT_ERROR, "Error with XML box size\n");
return OPJ_FALSE;
}
if(len > 0)
{
unsigned char *start;
start = cio_getbp(cio);
buf = (unsigned char*)opj_malloc(len);
cio_skip(cio, box->init_pos + box->length - cio_tell(cio));
memcpy(buf, start, len);
}
else
{
buf = (unsigned char*)opj_malloc(1);
*buf = 0;
}
if (cio_tell(cio) - box->init_pos != box->length)
{
opj_event_msg(cinfo, EVT_ERROR, "Error with XML Box\n");
free(buf);
return OPJ_FALSE;
}
XML_DATA_COLLECTOR.data = buf;
XML_DATA_COLLECTOR.len = len;
return OPJ_TRUE;
}/* jp2_read_colr() */
Reading could be done e.g. in:
opj_bool jp2_read_jp2h()
{
(...)
while(cio_tell(cio) < jp2h_end)
{
(...)
if(box.type == JP2_XML)
{
if( !jp2_read_xml(jp2, cio, &box, XML_DATA_COLLECTOR))
{
cio_seek(cio, box.init_pos + 8);
cio_skip(cio, box.length - 8);
}
jp2_read_boxhdr(cinfo, cio, &box);
continue;
}
(...)
}/* while(cio_tell(cio) < jp2h_end) */
(...)
}
Writing could be done (nearly) anywhere in 'jp2.c':
jp2_write_xml(cio, XML_DATA_COLLECTOR);
winfried