Possibility to choose to apply MCT (multiple component transform) enabled, and new...
[openjpeg.git] / mj2 / libopenjpeg_097 / jp2.c
1 /*\r
2 * Copyright (c) 2003-2004, Yannick Verschueren\r
3 * Copyright (c) 2003-2004,  Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium\r
4 * All rights reserved.\r
5 *\r
6 * Redistribution and use in source and binary forms, with or without\r
7 * modification, are permitted provided that the following conditions\r
8 * are met:\r
9 * 1. Redistributions of source code must retain the above copyright\r
10 *    notice, this list of conditions and the following disclaimer.\r
11 * 2. Redistributions in binary form must reproduce the above copyright\r
12 *    notice, this list of conditions and the following disclaimer in the\r
13 *    documentation and/or other materials provided with the distribution.\r
14 *\r
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'\r
16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
18 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\r
19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
25 * POSSIBILITY OF SUCH DAMAGE.\r
26 */\r
27 \r
28 #include <stdio.h>\r
29 #include <stdlib.h>\r
30 #include <string.h>\r
31 \r
32 #include "j2k.h"\r
33 #include "jp2.h"\r
34 #include "cio.h"\r
35 \r
36 #define JPIP_JPIP 0x6a706970\r
37 \r
38 #define JP2_JP   0x6a502020\r
39 #define JP2_FTYP 0x66747970\r
40 #define JP2_JP2H 0x6a703268\r
41 #define JP2_IHDR 0x69686472\r
42 #define JP2_COLR 0x636f6c72\r
43 #define JP2_JP2C 0x6a703263\r
44 #define JP2_URL  0x75726c20\r
45 #define JP2_DBTL 0x6474626c\r
46 #define JP2_BPCC 0x62706363\r
47 #define JP2_JP2  0x6a703220\r
48 \r
49 /*\r
50\r
51 * Read box headers\r
52 *\r
53 */\r
54 \r
55 int jp2_read_boxhdr(jp2_box_t * box)\r
56 {\r
57   box->init_pos = cio_tell();\r
58   box->length = cio_read(4);\r
59   box->type = cio_read(4);\r
60   if (box->length == 1) {\r
61     if (cio_read(4) != 0) {\r
62       fprintf(stderr, "Error: Cannot handle box sizes higher than 2^32\n");\r
63       return 1;\r
64     }\r
65     box->length = cio_read(4);\r
66     if (box->length == 0)\r
67       box->length = cio_numbytesleft() + 12;\r
68   } else if (box->length == 0) {\r
69     box->length = cio_numbytesleft() + 8;\r
70   }\r
71   return 0;\r
72 }\r
73 \r
74 /*\r
75\r
76 * Initialisation of a Standard JP2 structure\r
77 */\r
78 \r
79 int jp2_init_stdjp2(jp2_struct_t * jp2_struct)\r
80 {\r
81 \r
82   jp2_struct->comps =\r
83     (jp2_comps_t *) malloc(jp2_struct->numcomps * sizeof(jp2_comps_t));\r
84 \r
85   jp2_struct->precedence = 0;   /* PRECEDENCE*/\r
86   jp2_struct->approx = 0;   /* APPROX*/\r
87 \r
88   jp2_struct->brand = JP2_JP2;  /* BR         */\r
89   jp2_struct->minversion = 0;   /* MinV       */\r
90   jp2_struct->numcl = 1;\r
91   jp2_struct->cl = (unsigned int *) malloc(jp2_struct->numcl * sizeof(int));\r
92   jp2_struct->cl[0] = JP2_JP2;  /* CL0 : JP2  */\r
93 \r
94   jp2_struct->C = 7;      /* C : Always 7*/\r
95   jp2_struct->UnkC = 0;      /* UnkC, colorspace specified in colr box*/\r
96   jp2_struct->IPR = 0;      /* IPR, no intellectual property*/\r
97 \r
98   return 0;\r
99 }\r
100 \r
101 \r
102 void jp2_write_url(char *Idx_file)\r
103 {\r
104   unsigned int i;\r
105   char str[256];\r
106   jp2_box_t box;\r
107 \r
108   sprintf(str, "%s", Idx_file);\r
109 \r
110 \r
111   box.init_pos = cio_tell();\r
112   cio_skip(4);\r
113   cio_write(JP2_URL, 4);   /* DBTL*/\r
114   cio_write(0, 1);      /* VERS*/\r
115   cio_write(0, 3);      /* FLAG*/\r
116 \r
117   for (i = 0; i < strlen(str); i++) {\r
118     cio_write(str[i], 1);\r
119   }\r
120 \r
121   box.length = cio_tell() - box.init_pos;\r
122   cio_seek(box.init_pos);\r
123   cio_write(box.length, 4);     /*    L       */\r
124   cio_seek(box.init_pos + box.length);\r
125 }\r
126 \r
127 /*\r
128 * Read the IHDR box\r
129 *\r
130 * Image Header box\r
131 *\r
132 */\r
133 int jp2_read_ihdr(jp2_struct_t * jp2_struct)\r
134 {\r
135   jp2_box_t box;\r
136 \r
137   jp2_read_boxhdr(&box);\r
138   if (JP2_IHDR != box.type) {\r
139     fprintf(stderr, "Error: Expected IHDR Marker\n");\r
140     return 1;\r
141   }\r
142 \r
143   jp2_struct->h = cio_read(4);   /* HEIGHT*/\r
144   jp2_struct->w = cio_read(4);   /* WIDTH*/\r
145   jp2_struct->numcomps = cio_read(2);   /* NC*/\r
146 \r
147   jp2_struct->bpc = cio_read(1);   /* BPC*/\r
148 \r
149   jp2_struct->C = cio_read(1);   /* C */\r
150   jp2_struct->UnkC = cio_read(1);   /* UnkC*/\r
151   jp2_struct->IPR = cio_read(1);   /* IPR*/\r
152 \r
153   if (cio_tell() - box.init_pos != box.length) {\r
154     fprintf(stderr, "Error with IHDR Box\n");\r
155     return 1;\r
156   }\r
157   return 0;\r
158 }\r
159 \r
160 void jp2_write_ihdr(jp2_struct_t * jp2_struct)\r
161 {\r
162   jp2_box_t box;\r
163 \r
164   box.init_pos = cio_tell();\r
165   cio_skip(4);\r
166   cio_write(JP2_IHDR, 4);   /* IHDR*/\r
167 \r
168   cio_write(jp2_struct->h, 4);   /* HEIGHT*/\r
169   cio_write(jp2_struct->w, 4);   /* WIDTH*/\r
170   cio_write(jp2_struct->numcomps, 2);   /* NC*/\r
171 \r
172   cio_write(jp2_struct->bpc, 1);   /* BPC  */\r
173 \r
174   cio_write(jp2_struct->C, 1);   /* C : Always 7*/\r
175   cio_write(jp2_struct->UnkC, 1);   /* UnkC, colorspace unknow*/\r
176   cio_write(jp2_struct->IPR, 1);   /* IPR, no intellectual property*/\r
177 \r
178   box.length = cio_tell() - box.init_pos;\r
179   cio_seek(box.init_pos);\r
180   cio_write(box.length, 4);     /*    L       */\r
181   cio_seek(box.init_pos + box.length);\r
182 }\r
183 \r
184 \r
185 void jp2_write_bpcc(jp2_struct_t * jp2_struct)\r
186 {\r
187   unsigned int i;\r
188   jp2_box_t box;\r
189 \r
190   box.init_pos = cio_tell();\r
191   cio_skip(4);\r
192   cio_write(JP2_BPCC, 4);   /* BPCC*/\r
193 \r
194   for (i = 0; i < jp2_struct->numcomps; i++)\r
195     cio_write(jp2_struct->comps[i].bpcc, 1);\r
196 \r
197   box.length = cio_tell() - box.init_pos;\r
198   cio_seek(box.init_pos);\r
199   cio_write(box.length, 4);     /*    L       */\r
200   cio_seek(box.init_pos + box.length);\r
201 }\r
202 \r
203 \r
204 int jp2_read_bpcc(jp2_struct_t * jp2_struct)\r
205 {\r
206   unsigned int i;\r
207   jp2_box_t box;\r
208 \r
209   jp2_read_boxhdr(&box);\r
210   if (JP2_BPCC != box.type) {\r
211     fprintf(stderr, "Error: Expected BPCC Marker\n");\r
212     return 1;\r
213   }\r
214 \r
215   for (i = 0; i < jp2_struct->numcomps; i++)\r
216     jp2_struct->comps[i].bpcc = cio_read(1);\r
217 \r
218   if (cio_tell() - box.init_pos != box.length) {\r
219     fprintf(stderr, "Error with BPCC Box\n");\r
220     return 1;\r
221   }\r
222   return 0;\r
223 }\r
224 \r
225 void jp2_write_colr(jp2_struct_t * jp2_struct)\r
226 {\r
227   jp2_box_t box;\r
228 \r
229   box.init_pos = cio_tell();\r
230   cio_skip(4);\r
231   cio_write(JP2_COLR, 4);   /* COLR*/\r
232 \r
233   cio_write(jp2_struct->meth, 1);   /* METH*/\r
234   cio_write(jp2_struct->precedence, 1);   /* PRECEDENCE*/\r
235   cio_write(jp2_struct->approx, 1);   /* APPROX*/\r
236 \r
237   if (jp2_struct->meth == 1)\r
238     cio_write(jp2_struct->enumcs, 4);   /* EnumCS*/\r
239   else\r
240     cio_write(0, 1);      /* PROFILE (??)*/\r
241 \r
242   box.length = cio_tell() - box.init_pos;\r
243   cio_seek(box.init_pos);\r
244   cio_write(box.length, 4);     /*    L       */\r
245   cio_seek(box.init_pos + box.length);\r
246 }\r
247 \r
248 int jp2_read_colr(jp2_struct_t * jp2_struct)\r
249 {\r
250   jp2_box_t box;\r
251   int skip_len;\r
252 \r
253   jp2_read_boxhdr(&box);\r
254   do {\r
255     if (JP2_COLR != box.type) {\r
256       cio_skip(box.length - 8);\r
257       jp2_read_boxhdr(&box);\r
258     }\r
259   } while (JP2_COLR != box.type);\r
260 \r
261   jp2_struct->meth = cio_read(1);   /* METH*/\r
262   jp2_struct->precedence = cio_read(1);   /* PRECEDENCE*/\r
263   jp2_struct->approx = cio_read(1);   /* APPROX*/\r
264 \r
265   if (jp2_struct->meth == 1)\r
266     jp2_struct->enumcs = cio_read(4);   /* EnumCS*/\r
267   else {\r
268     /* SKIP PROFILE     */\r
269     skip_len = box.init_pos + box.length - cio_tell();\r
270     if (skip_len < 0) {\r
271       fprintf(stderr, "Error with JP2H box size\n");\r
272       return 1;\r
273     }\r
274     cio_skip(box.init_pos + box.length - cio_tell());\r
275   }\r
276 \r
277   if (cio_tell() - box.init_pos != box.length) {\r
278     fprintf(stderr, "Error with BPCC Box\n");\r
279     return 1;\r
280   }\r
281   return 0;\r
282 }\r
283 \r
284 /*\r
285 * Write the JP2H box\r
286 *\r
287 * JP2 Header box\r
288 *\r
289 */\r
290 void jp2_write_jp2h(jp2_struct_t * jp2_struct)\r
291 {\r
292   jp2_box_t box;\r
293 \r
294   box.init_pos = cio_tell();\r
295   cio_skip(4);;\r
296   cio_write(JP2_JP2H, 4);       /* JP2H */\r
297 \r
298   jp2_write_ihdr(jp2_struct);\r
299 \r
300   if (jp2_struct->bpc == 255)\r
301     jp2_write_bpcc(jp2_struct);\r
302   jp2_write_colr(jp2_struct);\r
303 \r
304   box.length = cio_tell() - box.init_pos;\r
305   cio_seek(box.init_pos);\r
306   cio_write(box.length, 4);     /*    L       */\r
307   cio_seek(box.init_pos + box.length);\r
308 }\r
309 \r
310 \r
311 /*\r
312 * Read the JP2H box\r
313 *\r
314 * JP2 Header box\r
315 *\r
316 */\r
317 int jp2_read_jp2h(jp2_struct_t * jp2_struct)\r
318 {\r
319   jp2_box_t box;\r
320   int skip_len;\r
321 \r
322   jp2_read_boxhdr(&box);\r
323   do {\r
324     if (JP2_JP2H != box.type) {\r
325       if (box.type == JP2_JP2C) {\r
326         fprintf(stderr, "Error: Expected JP2H Marker\n");\r
327         return 1;\r
328       }\r
329       cio_skip(box.length - 8);\r
330       jp2_read_boxhdr(&box);\r
331     }\r
332   } while (JP2_JP2H != box.type);\r
333 \r
334   if (jp2_read_ihdr(jp2_struct))\r
335     return 1;\r
336 \r
337   if (jp2_struct->bpc == 255) {\r
338     if (jp2_read_bpcc(jp2_struct))\r
339       return 1;\r
340   }\r
341 \r
342   if (jp2_read_colr(jp2_struct))\r
343     return 1;\r
344 \r
345   skip_len = box.init_pos + box.length - cio_tell();\r
346   if (skip_len < 0) {\r
347     fprintf(stderr, "Error with JP2H box size\n");\r
348     return 1;\r
349   }\r
350   cio_skip(box.init_pos + box.length - cio_tell());\r
351 \r
352   return 0;\r
353 }\r
354 \r
355 /*\r
356 * Write the FTYP box\r
357 *\r
358 * File type box\r
359 *\r
360 */\r
361 void jp2_write_ftyp(jp2_struct_t * jp2_struct)\r
362 {\r
363   unsigned int i;\r
364   jp2_box_t box;\r
365 \r
366   box.init_pos = cio_tell();\r
367   cio_skip(4);\r
368   cio_write(JP2_FTYP, 4);       /* FTYP       */\r
369 \r
370   cio_write(jp2_struct->brand, 4);      /* BR         */\r
371   cio_write(jp2_struct->minversion, 4); /* MinV       */\r
372 \r
373   for (i = 0; i < jp2_struct->numcl; i++)\r
374     cio_write(jp2_struct->cl[i], 4);    /* CL           */\r
375 \r
376   box.length = cio_tell() - box.init_pos;\r
377   cio_seek(box.init_pos);\r
378   cio_write(box.length, 4);     /*    L       */\r
379   cio_seek(box.init_pos + box.length);\r
380 }\r
381 \r
382 /*\r
383 * Read the FTYP box\r
384 *\r
385 * File type box\r
386 *\r
387 */\r
388 int jp2_read_ftyp(jp2_struct_t * jp2_struct)\r
389 {\r
390   int i;\r
391   jp2_box_t box;\r
392 \r
393   jp2_read_boxhdr(&box);\r
394 \r
395   if (JP2_FTYP != box.type) {\r
396     fprintf(stderr, "Error: Excpected FTYP Marker\n");\r
397     return 1;\r
398   }\r
399 \r
400   jp2_struct->brand = cio_read(4);      /* BR              */\r
401   jp2_struct->minversion = cio_read(4); /* MinV            */\r
402   jp2_struct->numcl = (box.length - 16) / 4;\r
403   jp2_struct->cl =\r
404     (unsigned int *) malloc(jp2_struct->numcl * sizeof(unsigned int));\r
405 \r
406   for (i = 0; i < (int) jp2_struct->numcl; i++)\r
407     jp2_struct->cl[i] = cio_read(4);    /* CLi */\r
408 \r
409   if (cio_tell() - box.init_pos != box.length) {\r
410     fprintf(stderr, "Error with FTYP Box\n");\r
411     return 1;\r
412   }\r
413   return 0;\r
414 }\r
415 \r
416 int jp2_write_jp2c(int j2k_codestream_len, int *j2k_codestream_offset,\r
417                    char *j2k_codestream)\r
418 {\r
419   jp2_box_t box;\r
420 \r
421   box.init_pos = cio_tell();\r
422   cio_skip(4);\r
423   cio_write(JP2_JP2C, 4);   /* JP2C*/\r
424 \r
425   *j2k_codestream_offset = cio_tell();\r
426   memcpy(cio_getbp(), j2k_codestream, j2k_codestream_len);\r
427 \r
428   box.length = 8 + j2k_codestream_len;\r
429   cio_seek(box.init_pos);\r
430   cio_write(box.length, 4);     /*    L       */\r
431   cio_seek(box.init_pos + box.length);\r
432 \r
433   return box.length;\r
434 }\r
435 \r
436 \r
437 int jp2_read_jp2c(unsigned int *j2k_codestream_len,\r
438                   unsigned int *j2k_codestream_offset)\r
439 {\r
440   jp2_box_t box;\r
441 \r
442   jp2_read_boxhdr(&box);\r
443   do {\r
444     if (JP2_JP2C != box.type) {\r
445       cio_skip(box.length - 8);\r
446       jp2_read_boxhdr(&box);\r
447     }\r
448   } while (JP2_JP2C != box.type);\r
449 \r
450   *j2k_codestream_offset = cio_tell();\r
451   *j2k_codestream_len = box.length - 8;\r
452 \r
453   return 0;\r
454 }\r
455 \r
456 void jp2_write_jp()\r
457 {\r
458   jp2_box_t box;\r
459 \r
460   box.init_pos = cio_tell();\r
461   cio_skip(4);\r
462   cio_write(JP2_JP, 4);      /* JP*/\r
463   cio_write(0x0d0a870a, 4);\r
464 \r
465   box.length = cio_tell() - box.init_pos;\r
466   cio_seek(box.init_pos);\r
467   cio_write(box.length, 4);     /*    L       */\r
468   cio_seek(box.init_pos + box.length);\r
469 }\r
470 \r
471 /*\r
472 * Read the JP box\r
473 *\r
474 * JPEG 2000 signature\r
475 *\r
476 * return 1 if error else 0\r
477 */\r
478 int jp2_read_jp()\r
479 {\r
480   jp2_box_t box;\r
481 \r
482   jp2_read_boxhdr(&box);\r
483   if (JP2_JP != box.type) {\r
484     fprintf(stderr, "Error: Expected JP Marker\n");\r
485     return 1;\r
486   }\r
487   if (0x0d0a870a != cio_read(4)) {\r
488     fprintf(stderr, "Error with JP Marker\n");\r
489     return 1;\r
490   }\r
491   if (cio_tell() - box.init_pos != box.length) {\r
492     fprintf(stderr, "Error with JP Box size\n");\r
493     return 1;\r
494   }\r
495   return 0;\r
496 \r
497 }\r
498 \r
499 \r
500 int jp2_read_struct(unsigned char *src, jp2_struct_t * jp2_struct, int len)\r
501 {\r
502   cio_init(src, len);\r
503 \r
504   if (jp2_read_jp())\r
505     return 1;\r
506   if (jp2_read_ftyp(jp2_struct))\r
507     return 1;\r
508   if (jp2_read_jp2h(jp2_struct))\r
509     return 1;\r
510   if (jp2_read_jp2c\r
511       (&jp2_struct->j2k_codestream_len,\r
512        &jp2_struct->j2k_codestream_offset))\r
513     return 1;\r
514   return 0;\r
515 }\r
516 \r
517 int jp2_wrap_j2k(jp2_struct_t * jp2_struct, char *j2k_codestream,\r
518                  char *output)\r
519 {\r
520   (void)output;\r
521   jp2_write_jp();\r
522   jp2_write_ftyp(jp2_struct);\r
523   jp2_write_jp2h(jp2_struct);\r
524 \r
525   jp2_write_jp2c(jp2_struct->j2k_codestream_len,\r
526                  &jp2_struct->j2k_codestream_offset, j2k_codestream);\r
527 \r
528   return cio_tell();\r
529 }\r