/*! * sreadHeaderJp2k() * * Input: data * size * &w (<optional return>) * &h (<optional return>) * &spp (<optional return>, samples/pixel) * Return: 0 if OK, 1 on error * * Notes: * (1) The metadata is stored as follows: * h: 4 bytes @ 48 * w: 4 bytes @ 52 * spp: 2 bytes @ 56 */ l_int32 sreadHeaderJp2k(const l_uint8 *data, size_t size, l_int32 *pw, l_int32 *ph, l_int32 *pspp) { l_int32 format, val, w, h, spp; PROCNAME("sreadHeaderJp2k"); if (pw) *pw = 0; if (ph) *ph = 0; if (pspp) *pspp = 0; if (!data) return ERROR_INT("data not defined", procName, 1); if (size < 60) return ERROR_INT("size < 60", procName, 1); findFileFormatBuffer(data, &format); if (format != IFF_JP2) return ERROR_INT("not jp2 file", procName, 1); val = *((l_uint32 *)data + 12); h = convertOnLittleEnd32(val); val = *((l_uint32 *)data + 13); w = convertOnLittleEnd32(val); val = *((l_uint16 *)data + 28); spp = convertOnLittleEnd16(val); if (w > MAX_JP2K_WIDTH || h > MAX_JP2K_HEIGHT) return ERROR_INT("unrealistically large sizes", procName, 1); if (pw) *pw = w; if (ph) *ph = h; if (pspp) *pspp = spp; return 0; }
/*! * sreadHeaderPng() * * Input: data * &width (<return>) * &height (<return>) * &bps (<return>, bits/sample) * &spp (<return>, samples/pixel) * &iscmap (<optional return>; input NULL to ignore) * Return: 0 if OK, 1 on error * * Notes: * (1) If there is a colormap, iscmap is returned as 1; else 0. */ l_int32 sreadHeaderPng(const l_uint8 *data, l_int32 *pwidth, l_int32 *pheight, l_int32 *pbps, l_int32 *pspp, l_int32 *piscmap) { l_uint8 colortype, bps; l_uint16 twobytes; l_uint16 *pshort; l_uint32 *pword; PROCNAME("sreadHeaderPng"); if (!data) return ERROR_INT("data not defined", procName, 1); if (!pwidth || !pheight || !pbps || !pspp) return ERROR_INT("input ptr(s) not defined", procName, 1); *pwidth = *pheight = *pbps = *pspp = 0; if (piscmap) *piscmap = 0; /* Check password */ if (data[0] != 137 || data[1] != 80 || data[2] != 78 || data[3] != 71 || data[4] != 13 || data[5] != 10 || data[6] != 26 || data[7] != 10) return ERROR_INT("not a valid png file", procName, 1); pword = (l_uint32 *)data; pshort = (l_uint16 *)data; *pwidth = convertOnLittleEnd32(pword[4]); *pheight = convertOnLittleEnd32(pword[5]); twobytes = convertOnLittleEnd16(pshort[12]); /* contains depth/sample */ /* and the color type */ colortype = twobytes & 0xff; /* color type */ bps = twobytes >> 8; /* bits/sample */ *pbps = bps; if (colortype == 2) /* RGB */ *pspp = 3; else if (colortype == 6) /* RGBA */ *pspp = 4; else /* palette or gray */ *pspp = 1; if (piscmap) { if (colortype & 1) /* palette: see png.h, PNG_COLOR_TYPE_... */ *piscmap = 1; else *piscmap = 0; } return 0; }
/*! * readHeaderMemJp2k() * * Input: data * size (at least 80) * &w (<optional return>) * &h (<optional return>) * &bps (<optional return>, bits/sample) * &spp (<optional return>, samples/pixel) * Return: 0 if OK, 1 on error * * Notes: * (1) The ISO/IEC reference for jpeg2000 is * http://www.jpeg.org/public/15444-1annexi.pdf * and the file format syntax begins at page 127. * (2) The Image Header Box begins with 'ihdr' = 0x69686472 in * big-endian order. This typically, but not always, starts * byte 44, with the big-endian data fields beginning at byte 48: * h: 4 bytes * w: 4 bytes * spp: 2 bytes * bps: 1 byte (contains bps - 1) */ l_int32 readHeaderMemJp2k(const l_uint8 *data, size_t size, l_int32 *pw, l_int32 *ph, l_int32 *pbps, l_int32 *pspp) { l_int32 format, val, w, h, bps, spp, loc, found, windex; l_uint8 ihdr[4] = {0x69, 0x68, 0x64, 0x72}; /* 'ihdr' */ PROCNAME("readHeaderMemJp2k"); if (pw) *pw = 0; if (ph) *ph = 0; if (pbps) *pbps = 0; if (pspp) *pspp = 0; if (!data) return ERROR_INT("data not defined", procName, 1); if (size < 80) return ERROR_INT("size < 80", procName, 1); findFileFormatBuffer(data, &format); if (format != IFF_JP2) return ERROR_INT("not jp2 file", procName, 1); /* Search for beginning of the Image Header Box: 'ihdr' */ arrayFindSequence(data, size, ihdr, 4, &loc, &found); if (!found) return ERROR_INT("image parameters not found", procName, 1); if (loc != 44) L_INFO("Beginning of ihdr is at byte %d\n", procName, loc); windex = loc / 4 + 1; val = *((l_uint32 *)data + windex); h = convertOnLittleEnd32(val); val = *((l_uint32 *)data + windex + 1); w = convertOnLittleEnd32(val); val = *((l_uint16 *)data + 2 * (windex + 2)); spp = convertOnLittleEnd16(val); bps = *(data + 4 * (windex + 2) + 2) + 1; if (w > MAX_JP2K_WIDTH || h > MAX_JP2K_HEIGHT) return ERROR_INT("unrealistically large sizes", procName, 1); if (pw) *pw = w; if (ph) *ph = h; if (pbps) *pbps = bps; if (pspp) *pspp = spp; return 0; }