46 #include <config_auto.h>
51 #include "allheaders.h"
62 static const l_int32 MAX_JP2K_WIDTH = 100000;
63 static const l_int32 MAX_JP2K_HEIGHT = 100000;
90 PROCNAME(
"readHeaderJp2k");
93 return ERROR_INT(
"filename not defined", procName, 1);
96 return ERROR_INT(
"image file not found", procName, 1);
125 PROCNAME(
"freadHeaderJp2k");
128 return ERROR_INT(
"fp not defined", procName, 1);
131 nread = fread(buf, 1,
sizeof(buf), fp);
132 if (nread !=
sizeof(buf))
133 return ERROR_INT(
"read failure", procName, 1);
180 l_int32 format, val, w, h, bps, spp, loc, found, windex, codec;
181 l_uint8 ihdr[4] = {0x69, 0x68, 0x64, 0x72};
183 PROCNAME(
"readHeaderMemJp2k");
189 if (pcodec) *pcodec = 0;
191 return ERROR_INT(
"data not defined", procName, 1);
193 return ERROR_INT(
"size < 80", procName, 1);
195 if (format != IFF_JP2)
196 return ERROR_INT(
"not jp2 file", procName, 1);
199 if (!memcmp(data,
"\xff\x4f\xff\x51", 4)) {
205 return ERROR_INT(
"image parameters not found", procName, 1);
206 windex = loc / 4 + 1;
210 L_INFO(
"Beginning of ihdr is at byte %d\n", procName, loc);
213 if (pcodec) *pcodec = codec;
216 if (size < 4 * (windex + 3))
217 return ERROR_INT(
"header size is too small", procName, 1);
218 val = *((l_uint32 *)data + windex);
219 h = convertOnLittleEnd32(val);
220 val = *((l_uint32 *)data + windex + 1);
221 w = convertOnLittleEnd32(val);
222 val = *((l_uint16 *)data + 2 * (windex + 2));
223 spp = convertOnLittleEnd16(val);
224 bps = *(data + 4 * (windex + 2) + 2) + 1;
226 if (size < 4 * (windex + 9))
227 return ERROR_INT(
"header size is too small", procName, 1);
228 val = *((l_uint32 *)data + windex);
229 w = convertOnLittleEnd32(val);
230 val = *((l_uint32 *)data + windex + 1);
231 h = convertOnLittleEnd32(val);
232 val = *((l_uint16 *)data + 2 * (windex + 8));
233 spp = convertOnLittleEnd16(val);
234 bps = *(data + 4 * (windex + 8) + 2) + 1;
237 lept_stderr(
"h = %d, w = %d, codec: %s, spp = %d, bps = %d\n", h, w,
242 return ERROR_INT(
"w and h must both be > 0", procName, 1);
243 if (w > MAX_JP2K_WIDTH || h > MAX_JP2K_HEIGHT)
244 return ERROR_INT(
"unrealistically large sizes", procName, 1);
245 if (spp != 1 && spp != 3 && spp != 4)
246 return ERROR_INT(
"spp must be in 1, 3 or 4", procName, 1);
247 if (bps != 8 && bps != 16)
248 return ERROR_INT(
"bps must be 8 or 16", procName, 1);
251 if (pspp) *pspp = spp;
252 if (pbps) *pbps = bps;
279 fgetJp2kResolution(FILE *fp,
285 l_uint16 xnum, ynum, xdenom, ydenom;
287 l_uint8 resc[4] = {0x72, 0x65, 0x73, 0x63};
289 l_float64 xres, yres, maxres;
291 PROCNAME(
"fgetJp2kResolution");
293 if (pxres) *pxres = 0;
294 if (pyres) *pyres = 0;
295 if (!pxres || !pyres)
296 return ERROR_INT(
"&xres and &yres not both defined", procName, 1);
298 return ERROR_INT(
"stream not opened", procName, 1);
307 L_WARNING(
"image resolution not found\n", procName);
311 if (nbytes < 80 || loc >= nbytes - 13) {
312 L_WARNING(
"image resolution found without enough space\n", procName);
319 ynum = data[loc + 5] << 8 | data[loc + 4];
320 ynum = convertOnLittleEnd16(ynum);
321 ydenom = data[loc + 7] << 8 | data[loc + 6];
322 ydenom = convertOnLittleEnd16(ydenom);
323 xnum = data[loc + 9] << 8 | data[loc + 8];
324 xnum = convertOnLittleEnd16(xnum);
325 xdenom = data[loc + 11] << 8 | data[loc + 10];
326 xdenom = convertOnLittleEnd16(xdenom);
327 if (ydenom == 0 || xdenom == 0) {
328 L_WARNING(
"bad data: ydenom or xdenom is 0\n", procName);
332 yexp = data[loc + 12];
333 xexp = data[loc + 13];
334 yres = ((l_float64)ynum / (l_float64)ydenom) * pow(10.0, (l_float64)yexp);
335 xres = ((l_float64)xnum / (l_float64)xdenom) * pow(10.0, (l_float64)xexp);
338 yres *= (300.0 / 11811.0);
339 xres *= (300.0 / 11811.0);
343 if (xres > maxres || yres > maxres) {
344 L_WARNING(
"ridiculously large resolution\n", procName);
346 *pyres = (l_int32)(yres + 0.5);
347 *pxres = (l_int32)(xres + 0.5);
l_ok findFileFormatBuffer(const l_uint8 *buf, l_int32 *pformat)
findFileFormatBuffer()
void lept_stderr(const char *fmt,...)
lept_stderr()
l_uint8 * l_binaryReadStream(FILE *fp, size_t *pnbytes)
l_binaryReadStream()
FILE * fopenReadStream(const char *filename)
fopenReadStream()
l_ok arrayFindSequence(const l_uint8 *data, size_t datalen, const l_uint8 *sequence, size_t seqlen, l_int32 *poffset, l_int32 *pfound)
arrayFindSequence()