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;
91 return ERROR_INT(
"filename not defined", __func__, 1);
94 return ERROR_INT(
"image file not found", __func__, 1);
124 return ERROR_INT(
"fp not defined", __func__, 1);
127 nread = fread(buf, 1,
sizeof(buf), fp);
128 if (nread !=
sizeof(buf))
129 return ERROR_INT(
"read failure", __func__, 1);
176 l_int32 format, val, w, h, bps, spp, loc, found, index, codec;
177 l_uint8 ihdr[4] = {0x69, 0x68, 0x64, 0x72};
183 if (pcodec) *pcodec = 0;
185 return ERROR_INT(
"data not defined", __func__, 1);
187 return ERROR_INT(
"size < 80", __func__, 1);
189 if (format != IFF_JP2)
190 return ERROR_INT(
"not jp2 file", __func__, 1);
193 if (!memcmp(data,
"\xff\x4f\xff\x51", 4)) {
199 return ERROR_INT(
"image parameters not found", __func__, 1);
204 L_INFO(
"Beginning of ihdr is at byte %d\n", __func__, loc);
207 if (pcodec) *pcodec = codec;
210 if (size < index + 4 * 3)
211 return ERROR_INT(
"header size is too small", __func__, 1);
212 val = *(l_uint32 *)(data + index);
213 h = convertOnLittleEnd32(val);
214 val = *(l_uint32 *)(data + index + 4);
215 w = convertOnLittleEnd32(val);
216 val = *(l_uint16 *)(data + index + 8);
217 spp = convertOnLittleEnd16(val);
218 bps = *(data + index + 10) + 1;
220 if (size < index + 4 * 9)
221 return ERROR_INT(
"header size is too small", __func__, 1);
222 val = *(l_uint32 *)(data + index);
223 w = convertOnLittleEnd32(val);
224 val = *(l_uint32 *)(data + index + 4);
225 h = convertOnLittleEnd32(val);
226 val = *(l_uint16 *)(data + index + 32);
227 spp = convertOnLittleEnd16(val);
228 bps = *(data + index + 34) + 1;
231 lept_stderr(
"h = %d, w = %d, codec: %s, spp = %d, bps = %d\n", h, w,
236 return ERROR_INT(
"w and h must both be > 0", __func__, 1);
237 if (w > MAX_JP2K_WIDTH || h > MAX_JP2K_HEIGHT)
238 return ERROR_INT(
"unrealistically large sizes", __func__, 1);
239 if (spp != 1 && spp != 3 && spp != 4)
240 return ERROR_INT(
"spp must be in 1, 3 or 4", __func__, 1);
241 if (bps != 8 && bps != 16)
242 return ERROR_INT(
"bps must be 8 or 16", __func__, 1);
245 if (pspp) *pspp = spp;
246 if (pbps) *pbps = bps;
273 fgetJp2kResolution(FILE *fp,
279 l_uint16 xnum, ynum, xdenom, ydenom;
281 l_uint8 resc[4] = {0x72, 0x65, 0x73, 0x63};
283 l_float64 xres, yres, maxres;
285 if (pxres) *pxres = 0;
286 if (pyres) *pyres = 0;
287 if (!pxres || !pyres)
288 return ERROR_INT(
"&xres and &yres not both defined", __func__, 1);
290 return ERROR_INT(
"stream not opened", __func__, 1);
299 L_WARNING(
"image resolution not found\n", __func__);
303 if (nbytes < 80 || loc >= nbytes - 13) {
304 L_WARNING(
"image resolution found without enough space\n", __func__);
311 ynum = data[loc + 5] << 8 | data[loc + 4];
312 ynum = convertOnLittleEnd16(ynum);
313 ydenom = data[loc + 7] << 8 | data[loc + 6];
314 ydenom = convertOnLittleEnd16(ydenom);
315 xnum = data[loc + 9] << 8 | data[loc + 8];
316 xnum = convertOnLittleEnd16(xnum);
317 xdenom = data[loc + 11] << 8 | data[loc + 10];
318 xdenom = convertOnLittleEnd16(xdenom);
319 if (ydenom == 0 || xdenom == 0) {
320 L_WARNING(
"bad data: ydenom or xdenom is 0\n", __func__);
324 yexp = data[loc + 12];
325 xexp = data[loc + 13];
326 yres = ((l_float64)ynum / (l_float64)ydenom) * pow(10.0, (l_float64)yexp);
327 xres = ((l_float64)xnum / (l_float64)xdenom) * pow(10.0, (l_float64)xexp);
330 yres *= (300.0 / 11811.0);
331 xres *= (300.0 / 11811.0);
335 if (xres > maxres || yres > maxres) {
336 L_WARNING(
"ridiculously large resolution\n", __func__);
338 *pyres = (l_int32)(yres + 0.5);
339 *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()