/* Markers with no parameters. All other markers are followed by a two
* byte length of the parameters. */ #define TEM 0x01 #define RST_begin 0xd0 #define RST_end 0xd7 #define SOI 0xd8 #define EOI 0xd9
while (p + 1 < data + length) { if (*p != 0xff) return CAIRO_INT_STATUS_UNSUPPORTED;
p++;
switch (*p) { /* skip fill bytes */ case 0xff:
p++; break;
case TEM: case SOI: case EOI:
p++; break;
case SOF0: case SOF1: case SOF2: case SOF3: case SOF5: case SOF6: case SOF7: case SOF9: case SOF10: case SOF11: case SOF13: case SOF14: case SOF15: /* Start of frame found. Extract the image parameters. */ if (p + 8 > data + length) return CAIRO_INT_STATUS_UNSUPPORTED;
/* First 12 bytes must be the JPEG 2000 signature box. */ if (length < ARRAY_LENGTH(_jpx_signature) ||
memcmp(p, _jpx_signature, ARRAY_LENGTH(_jpx_signature)) != 0) return CAIRO_INT_STATUS_UNSUPPORTED;
p += ARRAY_LENGTH(_jpx_signature);
/* Next box must be a File Type Box */ if (! _jpx_match_box (p, end, JPX_FILETYPE)) return CAIRO_INT_STATUS_UNSUPPORTED;
p = _jpx_next_box (p, end);
/* Locate the JP2 header box. */
p = _jpx_find_box (p, end, JPX_JP2_HEADER); if (!p) return CAIRO_INT_STATUS_UNSUPPORTED;
/* Step into the JP2 header box. First box must be the Image
* Header */
p = _jpx_get_box_contents (p); if (! _jpx_match_box (p, end, JPX_IMAGE_HEADER)) return CAIRO_INT_STATUS_UNSUPPORTED;
/* Get the image info */
p = _jpx_get_box_contents (p); return _jpx_extract_info (p, info, end);
}
/* The first chunk must be IDHR. IDHR has 13 bytes of data plus
* the 12 bytes of overhead for the chunk. */ if (p + 13 + 12 > end) return CAIRO_INT_STATUS_UNSUPPORTED;
p += 4; if (get_unaligned_be32 (p) != PNG_IHDR) return CAIRO_INT_STATUS_UNSUPPORTED;
p += 4;
info->width = get_unaligned_be32 (p);
p += 4;
info->height = get_unaligned_be32 (p);
return CAIRO_STATUS_SUCCESS;
}
staticconstunsignedchar *
_jbig2_find_data_end (constunsignedchar *p, constunsignedchar *end, int type)
{ unsignedchar end_seq[2]; int mmr;
/* Segments of type "Immediate generic region" may have an * unspecified data length. The JBIG2 specification specifies the
* method to find the end of the data for these segments. */ if (type == 36 || type == 38 || type == 39) { if (p + 18 < end) {
mmr = p[17] & 0x01; if (mmr) { /* MMR encoding ends with 0x00, 0x00 */
end_seq[0] = 0x00;
end_seq[1] = 0x00;
} else { /* Template encoding ends with 0xff, 0xac */
end_seq[0] = 0xff;
end_seq[1] = 0xac;
}
p += 18; while (p < end) { if (p[0] == end_seq[0] && p[1] == end_seq[1]) { /* Skip the 2 terminating bytes and the 4 byte row count that follows. */
p += 6; if (p < end) return p;
}
p++;
}
}
}
return NULL;
}
staticconstunsignedchar *
_jbig2_get_next_segment (constunsignedchar *p, constunsignedchar *end, int *type, constunsignedchar **data, unsignedlong *data_len)
{ unsignedlong seg_num;
cairo_bool_t big_page_size; int num_segs; int ref_seg_bytes; int referred_size;
p += num_segs * referred_size;
p += big_page_size ? 4 : 1; if (p + 4 >= end) return NULL;
*data_len = get_unaligned_be32 (p);
p += 4;
*data = p;
if (*data_len == 0xffffffff) { /* if data length is -1 we have to scan through the data to find the end */
p = _jbig2_find_data_end (*data, end, *type); if (!p || p >= end) return NULL;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.