And I'm guessing the problem is in jas_iccprof_load():
jas_iccprof_t *jas_iccprof_load(jas_stream_t *in)
{
jas_iccprof_t *prof;
int numtags;
long curoff;
long reloff;
long prevoff;
jas_iccsig_t type;
jas_iccattrval_t *attrval;
jas_iccattrval_t *prevattrval;
jas_icctagtabent_t *tagtabent;
jas_iccattrvalinfo_t *attrvalinfo;
int i;
int len;
prof = 0;
attrval = 0;
if (!(prof = jas_iccprof_create())) {
goto error;
}
if (jas_iccprof_readhdr(in, &prof->hdr)) {
jas_eprintf("cannot get header\n");
goto error;
}
So I added some debug traces, and the problem is that jas_stream_gobble() returns 0, not 44. Here is the function, complete with silly backwards loop.
int jas_stream_gobble(jas_stream_t *stream, int n)
{
int m;
m = n;
for (m = n; m > 0; --m) {
if (jas_stream_getc(stream) == EOF) {
return n - m;
}
}
return n;
}
Since it doesn't seem to use the expected 44 bytes of this header, I tried removing the check. Note that when writing the equivalent icc profile, it does add 44 padding bytes, so someone hasn't read the spec properly... (i.e. either the padding is optional or it isn't and the file is invalid). Anyway, libjasper should never abort(), that is just plain wrong (and dangerous).
Sadly removing the check just shifts us to the error "cannot get tab table". Ok, that's all I have for now. Somebody is going to have to read the spec and see where libjasper is going wrong. And also remove all those ridiculous abort()s.
Here is the code in question:
switch (dec->colr- >data.colr. method) { setclrspc( dec->image, jp2_getcs( &dec->colr- >data.colr) ); createfrombuf( dec->colr- >data.colr. iccp, >colr-> data.colr. iccplen) ; gethdr( iccprof, &icchdr); setclrspc( dec->image, fromiccpcs( icchdr. colorspc) ); image-> cmprof_ = jas_cmprof_ createfromiccpr of(iccprof) ; dec->image- >cmprof_ ); destroy( iccprof) ;
case JP2_COLR_ENUM:
jas_image_
break;
case JP2_COLR_ICC:
iccprof = jas_iccprof_
dec-
assert(iccprof);
jas_iccprof_
jas_eprintf("ICC Profile CS %08x\n", icchdr.colorspc);
jas_image_
dec->
assert(
jas_iccprof_
break;
}
And in base/jas_icc.c:
jas_iccprof_t *jas_iccprof_ createfrombuf( uchar *buf, int len) memopen( JAS_CAST( char *, buf), len))) load(in) )) close(in) ;
{
jas_stream_t *in;
jas_iccprof_t *prof;
if (!(in = jas_stream_
goto error;
if (!(prof = jas_iccprof_
goto error;
jas_stream_
return prof;
error:
return 0;
}
And I'm guessing the problem is in jas_iccprof_load():
jas_iccprof_t *jas_iccprof_ load(jas_ stream_ t *in) info_t *attrvalinfo;
{
jas_iccprof_t *prof;
int numtags;
long curoff;
long reloff;
long prevoff;
jas_iccsig_t type;
jas_iccattrval_t *attrval;
jas_iccattrval_t *prevattrval;
jas_icctagtabent_t *tagtabent;
jas_iccattrval
int i;
int len;
prof = 0;
attrval = 0;
if (!(prof = jas_iccprof_ create( ))) {
goto error;
}
if (jas_iccprof_ readhdr( in, &prof->hdr)) { "cannot get header\n");
jas_eprintf(
goto error;
}
.. Looks familiar. jas_iccprof_ readhdr( ):
static int jas_iccprof_ readhdr( jas_stream_ t *in, jas_icchdr_t *hdr) 32(in, &hdr->size) || iccgetuint32( in, &hdr->cmmtype) || iccgetuint32( in, &hdr->version) || iccgetuint32( in, &hdr->clas) || iccgetuint32( in, &hdr->colorspc) || iccgetuint32( in, &hdr->refcolorspc) || iccgettime( in, &hdr->ctime) || iccgetuint32( in, &hdr->magic) || iccgetuint32( in, &hdr->platform) || iccgetuint32( in, &hdr->flags) || iccgetuint32( in, &hdr->maker) || iccgetuint32( in, &hdr->model) || iccgetuint64( in, &hdr->attr) || iccgetuint32( in, &hdr->intent) || iccgetxyz( in, &hdr->illum) || iccgetuint32( in, &hdr->creator) || stream_ gobble( in, 44) != 44)
{
if (jas_iccgetuint
jas_
jas_
jas_
jas_
jas_
jas_
jas_
jas_
jas_
jas_
jas_
jas_
jas_
jas_
jas_
jas_
return -1;
return 0;
}
So I added some debug traces, and the problem is that jas_stream_gobble() returns 0, not 44. Here is the function, complete with silly backwards loop.
int jas_stream_ gobble( jas_stream_ t *stream, int n) getc(stream) == EOF) {
{
int m;
m = n;
for (m = n; m > 0; --m) {
if (jas_stream_
return n - m;
}
}
return n;
}
Since it doesn't seem to use the expected 44 bytes of this header, I tried removing the check. Note that when writing the equivalent icc profile, it does add 44 padding bytes, so someone hasn't read the spec properly... (i.e. either the padding is optional or it isn't and the file is invalid). Anyway, libjasper should never abort(), that is just plain wrong (and dangerous).
Sadly removing the check just shifts us to the error "cannot get tab table". Ok, that's all I have for now. Somebody is going to have to read the spec and see where libjasper is going wrong. And also remove all those ridiculous abort()s.