]> Creatis software - gdcm.git/blob - src/gdcmopenjpeg/libopenjpeg/jp2.c
ENH: This time for real. Install is ok. STYLE: some minor stuff
[gdcm.git] / src / gdcmopenjpeg / libopenjpeg / jp2.c
1 /*
2  * Copyright (c) 2004, Yannick Verschueren
3  * Copyright (c) 2005, HervĂ© Drolon, FreeImage Team
4  * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
17  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
20  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  * POSSIBILITY OF SUCH DAMAGE.
27  */
28
29 #include "opj_includes.h"
30
31 /** @defgroup JP2 JP2 - JPEG-2000 file format reader/writer */
32 /*@{*/
33
34 /** @name Local static functions */
35 /*@{*/
36
37 /**
38 Read box headers
39 @param cinfo Codec context info
40 @param cio Input stream
41 @param box
42 @return Returns true if successful, returns false otherwise
43 */
44 static bool jp2_read_boxhdr(opj_common_ptr cinfo, opj_cio_t *cio, opj_jp2_box_t *box);
45 /*static void jp2_write_url(opj_cio_t *cio, char *Idx_file);*/
46 /**
47 Read the IHDR box - Image Header box
48 @param jp2 JP2 handle
49 @param cio Input buffer stream
50 @return Returns true if successful, returns false otherwise
51 */
52 static bool jp2_read_ihdr(opj_jp2_t *jp2, opj_cio_t *cio);
53 static void jp2_write_ihdr(opj_jp2_t *jp2, opj_cio_t *cio);
54 static void jp2_write_bpcc(opj_jp2_t *jp2, opj_cio_t *cio);
55 static bool jp2_read_bpcc(opj_jp2_t *jp2, opj_cio_t *cio);
56 static void jp2_write_colr(opj_jp2_t *jp2, opj_cio_t *cio);
57 static bool jp2_read_colr(opj_jp2_t *jp2, opj_cio_t *cio);
58 /**
59 Write the JP2H box - JP2 Header box
60 @param jp2 JP2 handle
61 @param cio Output buffer stream
62 */
63 static void jp2_write_jp2h(opj_jp2_t *jp2, opj_cio_t *cio);
64 /**
65 Read the JP2H box - JP2 Header box
66 @param jp2 JP2 handle
67 @param cio Input buffer stream
68 @return Returns true if successful, returns false otherwise
69 */
70 static bool jp2_read_jp2h(opj_jp2_t *jp2, opj_cio_t *cio);
71 /**
72 Write the FTYP box - File type box
73 @param jp2 JP2 handle
74 @param cio Output buffer stream
75 */
76 static void jp2_write_ftyp(opj_jp2_t *jp2, opj_cio_t *cio);
77 /**
78 Read the FTYP box - File type box
79 @param jp2 JP2 handle
80 @param cio Input buffer stream
81 @return Returns true if successful, returns false otherwise
82 */
83 static bool jp2_read_ftyp(opj_jp2_t *jp2, opj_cio_t *cio);
84 static int jp2_write_jp2c(opj_jp2_t *jp2, opj_cio_t *cio, opj_image_t *image, char *index);
85 static bool jp2_read_jp2c(opj_jp2_t *jp2, opj_cio_t *cio, unsigned int *j2k_codestream_length, unsigned int *j2k_codestream_offset);
86 static void jp2_write_jp(opj_cio_t *cio);
87 /**
88 Read the JP box - JPEG 2000 signature
89 @param jp2 JP2 handle
90 @param cio Input buffer stream
91 @return Returns true if successful, returns false otherwise
92 */
93 static bool jp2_read_jp(opj_jp2_t *jp2, opj_cio_t *cio);
94 /**
95 Decode the structure of a JP2 file
96 @param jp2 JP2 handle
97 @param cio Input buffer stream
98 @return Returns true if successful, returns false otherwise
99 */
100 static bool jp2_read_struct(opj_jp2_t *jp2, opj_cio_t *cio);
101
102 /*@}*/
103
104 /*@}*/
105
106 /* ----------------------------------------------------------------------- */
107
108 static bool jp2_read_boxhdr(opj_common_ptr cinfo, opj_cio_t *cio, opj_jp2_box_t *box) {
109   box->init_pos = cio_tell(cio);
110   box->length = cio_read(cio, 4);
111   box->type = cio_read(cio, 4);
112   if (box->length == 1) {
113     if (cio_read(cio, 4) != 0) {
114       opj_event_msg(cinfo, EVT_ERROR, "Cannot handle box sizes higher than 2^32\n");
115       return false;
116     }
117     box->length = cio_read(cio, 4);
118     if (box->length == 0) 
119       box->length = cio_numbytesleft(cio) + 12;
120   }
121   else if (box->length == 0) {
122     box->length = cio_numbytesleft(cio) + 8;
123   }
124   
125   return true;
126 }
127
128 #if 0
129 static void jp2_write_url(opj_cio_t *cio, char *Idx_file) {
130   unsigned int i;
131   opj_jp2_box_t box;
132
133   box.init_pos = cio_tell(cio);
134   cio_skip(cio, 4);
135   cio_write(cio, JP2_URL, 4);  /* DBTL */
136   cio_write(cio, 0, 1);    /* VERS */
137   cio_write(cio, 0, 3);    /* FLAG */
138
139   if(Idx_file) {
140     for (i = 0; i < strlen(Idx_file); i++) {
141       cio_write(cio, Idx_file[i], 1);
142     }
143   }
144
145   box.length = cio_tell(cio) - box.init_pos;
146   cio_seek(cio, box.init_pos);
147   cio_write(cio, box.length, 4);  /* L */
148   cio_seek(cio, box.init_pos + box.length);
149 }
150 #endif
151
152 static bool jp2_read_ihdr(opj_jp2_t *jp2, opj_cio_t *cio) {
153   opj_jp2_box_t box;
154
155   opj_common_ptr cinfo = jp2->cinfo;
156
157   jp2_read_boxhdr(cinfo, cio, &box);
158   if (JP2_IHDR != box.type) {
159     opj_event_msg(cinfo, EVT_ERROR, "Expected IHDR Marker\n");
160     return false;
161   }
162
163   jp2->h = cio_read(cio, 4);      /* HEIGHT */
164   jp2->w = cio_read(cio, 4);      /* WIDTH */
165   jp2->numcomps = cio_read(cio, 2);  /* NC */
166   jp2->comps = (opj_jp2_comps_t*) opj_malloc(jp2->numcomps * sizeof(opj_jp2_comps_t));
167
168   jp2->bpc = cio_read(cio, 1);    /* BPC */
169
170   jp2->C = cio_read(cio, 1);      /* C */
171   jp2->UnkC = cio_read(cio, 1);    /* UnkC */
172   jp2->IPR = cio_read(cio, 1);    /* IPR */
173
174   if (cio_tell(cio) - box.init_pos != box.length) {
175     opj_event_msg(cinfo, EVT_ERROR, "Error with IHDR Box\n");
176     return false;
177   }
178
179   return true;
180 }
181
182 static void jp2_write_ihdr(opj_jp2_t *jp2, opj_cio_t *cio) {
183   opj_jp2_box_t box;
184
185   box.init_pos = cio_tell(cio);
186   cio_skip(cio, 4);
187   cio_write(cio, JP2_IHDR, 4);    /* IHDR */
188
189   cio_write(cio, jp2->h, 4);      /* HEIGHT */
190   cio_write(cio, jp2->w, 4);      /* WIDTH */
191   cio_write(cio, jp2->numcomps, 2);  /* NC */
192
193   cio_write(cio, jp2->bpc, 1);    /* BPC */
194
195   cio_write(cio, jp2->C, 1);      /* C : Always 7 */
196   cio_write(cio, jp2->UnkC, 1);    /* UnkC, colorspace unknown */
197   cio_write(cio, jp2->IPR, 1);    /* IPR, no intellectual property */
198
199   box.length = cio_tell(cio) - box.init_pos;
200   cio_seek(cio, box.init_pos);
201   cio_write(cio, box.length, 4);  /* L */
202   cio_seek(cio, box.init_pos + box.length);
203 }
204
205 static void jp2_write_bpcc(opj_jp2_t *jp2, opj_cio_t *cio) {
206   unsigned int i;
207   opj_jp2_box_t box;
208
209   box.init_pos = cio_tell(cio);
210   cio_skip(cio, 4);
211   cio_write(cio, JP2_BPCC, 4);  /* BPCC */
212
213   for (i = 0; i < jp2->numcomps; i++) {
214     cio_write(cio, jp2->comps[i].bpcc, 1);
215   }
216
217   box.length = cio_tell(cio) - box.init_pos;
218   cio_seek(cio, box.init_pos);
219   cio_write(cio, box.length, 4);  /* L */
220   cio_seek(cio, box.init_pos + box.length);
221 }
222
223
224 static bool jp2_read_bpcc(opj_jp2_t *jp2, opj_cio_t *cio) {
225   unsigned int i;
226   opj_jp2_box_t box;
227
228   opj_common_ptr cinfo = jp2->cinfo;
229
230   jp2_read_boxhdr(cinfo, cio, &box);
231   if (JP2_BPCC != box.type) {
232     opj_event_msg(cinfo, EVT_ERROR, "Expected BPCC Marker\n");
233     return false;
234   }
235
236   for (i = 0; i < jp2->numcomps; i++) {
237     jp2->comps[i].bpcc = cio_read(cio, 1);
238   }
239
240   if (cio_tell(cio) - box.init_pos != box.length) {
241     opj_event_msg(cinfo, EVT_ERROR, "Error with BPCC Box\n");
242     return false;
243   }
244
245   return true;
246 }
247
248 static void jp2_write_colr(opj_jp2_t *jp2, opj_cio_t *cio) {
249   opj_jp2_box_t box;
250
251   box.init_pos = cio_tell(cio);
252   cio_skip(cio, 4);
253   cio_write(cio, JP2_COLR, 4);    /* COLR */
254
255   cio_write(cio, jp2->meth, 1);    /* METH */
256   cio_write(cio, jp2->precedence, 1);  /* PRECEDENCE */
257   cio_write(cio, jp2->approx, 1);    /* APPROX */
258
259   if (jp2->meth == 1) {
260     cio_write(cio, jp2->enumcs, 4);  /* EnumCS */
261   } else {
262     cio_write(cio, 0, 1);      /* PROFILE (??) */
263   }
264
265   box.length = cio_tell(cio) - box.init_pos;
266   cio_seek(cio, box.init_pos);
267   cio_write(cio, box.length, 4);  /* L */
268   cio_seek(cio, box.init_pos + box.length);
269 }
270
271 static bool jp2_read_colr(opj_jp2_t *jp2, opj_cio_t *cio) {
272   opj_jp2_box_t box;
273   int skip_len;
274
275   opj_common_ptr cinfo = jp2->cinfo;
276
277   jp2_read_boxhdr(cinfo, cio, &box);
278   do {
279     if (JP2_COLR != box.type) {
280       cio_skip(cio, box.length - 8);
281       jp2_read_boxhdr(cinfo, cio, &box);
282     }
283   } while(JP2_COLR != box.type);
284
285   jp2->meth = cio_read(cio, 1);    /* METH */
286   jp2->precedence = cio_read(cio, 1);  /* PRECEDENCE */
287   jp2->approx = cio_read(cio, 1);    /* APPROX */
288
289   if (jp2->meth == 1) {
290     jp2->enumcs = cio_read(cio, 4);  /* EnumCS */
291   } else {
292     /* skip PROFILE */
293     skip_len = box.init_pos + box.length - cio_tell(cio);
294     if (skip_len < 0) {
295       opj_event_msg(cinfo, EVT_ERROR, "Error with JP2H box size\n");
296       return false;
297     }
298     cio_skip(cio, box.init_pos + box.length - cio_tell(cio));
299   }
300
301   if (cio_tell(cio) - box.init_pos != box.length) {
302     opj_event_msg(cinfo, EVT_ERROR, "Error with BPCC Box\n");
303     return false;
304   }
305   return true;
306 }
307
308 static void jp2_write_jp2h(opj_jp2_t *jp2, opj_cio_t *cio) {
309   opj_jp2_box_t box;
310
311   box.init_pos = cio_tell(cio);
312   cio_skip(cio, 4);
313   cio_write(cio, JP2_JP2H, 4);  /* JP2H */
314
315   jp2_write_ihdr(jp2, cio);
316
317   if (jp2->bpc == 255) {
318     jp2_write_bpcc(jp2, cio);
319   }
320   jp2_write_colr(jp2, cio);
321
322   box.length = cio_tell(cio) - box.init_pos;
323   cio_seek(cio, box.init_pos);
324   cio_write(cio, box.length, 4);  /* L */
325   cio_seek(cio, box.init_pos + box.length);
326 }
327
328 static bool jp2_read_jp2h(opj_jp2_t *jp2, opj_cio_t *cio) {
329   opj_jp2_box_t box;
330   int skip_len;
331
332   opj_common_ptr cinfo = jp2->cinfo;
333
334   jp2_read_boxhdr(cinfo, cio, &box);
335   do {
336     if (JP2_JP2H != box.type) {
337       if (box.type == JP2_JP2C) {
338         opj_event_msg(cinfo, EVT_ERROR, "Expected JP2H Marker\n");
339         return false;
340       }
341       cio_skip(cio, box.length - 8);
342       jp2_read_boxhdr(cinfo, cio, &box);
343     }
344   } while(JP2_JP2H != box.type);
345
346   if (!jp2_read_ihdr(jp2, cio))
347     return false;
348
349   if (jp2->bpc == 255) {
350     if (!jp2_read_bpcc(jp2, cio))
351       return false;
352   }
353   if (!jp2_read_colr(jp2, cio))
354     return false;
355
356   skip_len = box.init_pos + box.length - cio_tell(cio);
357   if (skip_len < 0) {
358     opj_event_msg(cinfo, EVT_ERROR, "Error with JP2H Box\n");
359     return false;
360   }
361   cio_skip(cio, box.init_pos + box.length - cio_tell(cio));
362
363   return true;
364 }
365
366 static void jp2_write_ftyp(opj_jp2_t *jp2, opj_cio_t *cio) {
367   unsigned int i;
368   opj_jp2_box_t box;
369
370   box.init_pos = cio_tell(cio);
371   cio_skip(cio, 4);
372   cio_write(cio, JP2_FTYP, 4);    /* FTYP */
373
374   cio_write(cio, jp2->brand, 4);    /* BR */
375   cio_write(cio, jp2->minversion, 4);  /* MinV */
376
377   for (i = 0; i < jp2->numcl; i++) {
378     cio_write(cio, jp2->cl[i], 4);  /* CL */
379   }
380
381   box.length = cio_tell(cio) - box.init_pos;
382   cio_seek(cio, box.init_pos);
383   cio_write(cio, box.length, 4);  /* L */
384   cio_seek(cio, box.init_pos + box.length);
385 }
386
387 static bool jp2_read_ftyp(opj_jp2_t *jp2, opj_cio_t *cio) {
388   int i;
389   opj_jp2_box_t box;
390
391   opj_common_ptr cinfo = jp2->cinfo;
392
393   jp2_read_boxhdr(cinfo, cio, &box);
394
395   if (JP2_FTYP != box.type) {
396     opj_event_msg(cinfo, EVT_ERROR, "Expected FTYP Marker\n");
397     return false;
398   }
399
400   jp2->brand = cio_read(cio, 4);    /* BR */
401   jp2->minversion = cio_read(cio, 4);  /* MinV */
402   jp2->numcl = (box.length - 16) / 4;
403   jp2->cl = (unsigned int *) opj_malloc(jp2->numcl * sizeof(unsigned int));
404
405   for (i = 0; i < (int)jp2->numcl; i++) {
406     jp2->cl[i] = cio_read(cio, 4);  /* CLi */
407   }
408
409   if (cio_tell(cio) - box.init_pos != box.length) {
410     opj_event_msg(cinfo, EVT_ERROR, "Error with FTYP Box\n");
411     return false;
412   }
413
414   return true;
415 }
416
417 static int jp2_write_jp2c(opj_jp2_t *jp2, opj_cio_t *cio, opj_image_t *image, char *index) {
418   unsigned int j2k_codestream_offset, j2k_codestream_length;
419   opj_jp2_box_t box;
420
421   opj_j2k_t *j2k = jp2->j2k;
422
423   box.init_pos = cio_tell(cio);
424   cio_skip(cio, 4);
425   cio_write(cio, JP2_JP2C, 4);  /* JP2C */
426
427   /* J2K encoding */
428   j2k_codestream_offset = cio_tell(cio);
429   if(!j2k_encode(j2k, cio, image, index)) {
430     opj_event_msg(j2k->cinfo, EVT_ERROR, "Failed to encode image\n");
431     return 0;
432   }
433   j2k_codestream_length = cio_tell(cio) - j2k_codestream_offset;
434
435   jp2->j2k_codestream_offset = j2k_codestream_offset;
436   jp2->j2k_codestream_length = j2k_codestream_length;
437
438   box.length = 8 + jp2->j2k_codestream_length;
439   cio_seek(cio, box.init_pos);
440   cio_write(cio, box.length, 4);  /* L */
441   cio_seek(cio, box.init_pos + box.length);
442
443   return box.length;
444 }
445
446 static bool jp2_read_jp2c(opj_jp2_t *jp2, opj_cio_t *cio, unsigned int *j2k_codestream_length, unsigned int *j2k_codestream_offset) {
447   opj_jp2_box_t box;
448
449   opj_common_ptr cinfo = jp2->cinfo;
450
451   jp2_read_boxhdr(cinfo, cio, &box);
452   do {
453     if(JP2_JP2C != box.type) {
454       cio_skip(cio, box.length - 8);
455       jp2_read_boxhdr(cinfo, cio, &box);
456     }
457   } while(JP2_JP2C != box.type);
458
459   *j2k_codestream_offset = cio_tell(cio);
460   *j2k_codestream_length = box.length - 8;
461
462   return true;
463 }
464
465 static void jp2_write_jp(opj_cio_t *cio) {
466   opj_jp2_box_t box;
467
468   box.init_pos = cio_tell(cio);
469   cio_skip(cio, 4);
470   cio_write(cio, JP2_JP, 4);    /* JP2 signature */
471   cio_write(cio, 0x0d0a870a, 4);
472
473   box.length = cio_tell(cio) - box.init_pos;
474   cio_seek(cio, box.init_pos);
475   cio_write(cio, box.length, 4);  /* L */
476   cio_seek(cio, box.init_pos + box.length);
477 }
478
479 static bool jp2_read_jp(opj_jp2_t *jp2, opj_cio_t *cio) {
480   opj_jp2_box_t box;
481
482   opj_common_ptr cinfo = jp2->cinfo;
483
484   jp2_read_boxhdr(cinfo, cio, &box);
485   if (JP2_JP != box.type) {
486     opj_event_msg(cinfo, EVT_ERROR, "Expected JP Marker\n");
487     return false;
488   }
489   if (0x0d0a870a != cio_read(cio, 4)) {
490     opj_event_msg(cinfo, EVT_ERROR, "Error with JP Marker\n");
491     return false;
492   }
493   if (cio_tell(cio) - box.init_pos != box.length) {
494     opj_event_msg(cinfo, EVT_ERROR, "Error with JP Box size\n");
495     return false;
496   }
497
498   return true;
499 }
500
501
502 static bool jp2_read_struct(opj_jp2_t *jp2, opj_cio_t *cio) {
503   if (!jp2_read_jp(jp2, cio))
504     return false;
505   if (!jp2_read_ftyp(jp2, cio))
506     return false;
507   if (!jp2_read_jp2h(jp2, cio))
508     return false;
509   if (!jp2_read_jp2c(jp2, cio, &jp2->j2k_codestream_length, &jp2->j2k_codestream_offset))
510     return false;
511   
512   return true;
513 }
514
515 /* ----------------------------------------------------------------------- */
516 /* JP2 decoder interface                                             */
517 /* ----------------------------------------------------------------------- */
518
519 opj_jp2_t* jp2_create_decompress(opj_common_ptr cinfo) {
520   opj_jp2_t *jp2 = (opj_jp2_t*)opj_malloc(sizeof(opj_jp2_t));
521   if(jp2) {
522     jp2->cinfo = cinfo;
523     /* create the J2K codec */
524     jp2->j2k = j2k_create_decompress(cinfo);
525     if(jp2->j2k == NULL) {
526       jp2_destroy_decompress(jp2);
527       return NULL;
528     }
529   }
530   return jp2;
531 }
532
533 void jp2_destroy_decompress(opj_jp2_t *jp2) {
534   if(jp2) {
535     /* destroy the J2K codec */
536     j2k_destroy_decompress(jp2->j2k);
537
538     if(jp2->comps) {
539       opj_free(jp2->comps);
540     }
541     if(jp2->cl) {
542       opj_free(jp2->cl);
543     }
544     opj_free(jp2);
545   }
546 }
547
548 void jp2_setup_decoder(opj_jp2_t *jp2, opj_dparameters_t *parameters) {
549   /* setup the J2K codec */
550   j2k_setup_decoder(jp2->j2k, parameters);
551   /* further JP2 initializations go here */
552 }
553
554 opj_image_t* jp2_decode(opj_jp2_t *jp2, opj_cio_t *cio) {
555   opj_common_ptr cinfo;
556   opj_image_t *image = NULL;
557
558   if(!jp2 || !cio) {
559     return NULL;
560   }
561
562   cinfo = jp2->cinfo;
563
564   /* JP2 decoding */
565   if(!jp2_read_struct(jp2, cio)) {
566     opj_event_msg(cinfo, EVT_ERROR, "Failed to decode jp2 structure\n");
567     return NULL;
568   }
569
570   /* J2K decoding */
571   image = j2k_decode(jp2->j2k, cio);
572   if(!image) {
573     opj_event_msg(cinfo, EVT_ERROR, "Failed to decode J2K image\n");
574   }
575
576   return image;
577 }
578
579 /* ----------------------------------------------------------------------- */
580 /* JP2 encoder interface                                             */
581 /* ----------------------------------------------------------------------- */
582
583 opj_jp2_t* jp2_create_compress(opj_common_ptr cinfo) {
584   opj_jp2_t *jp2 = (opj_jp2_t*)opj_malloc(sizeof(opj_jp2_t));
585   if(jp2) {
586     jp2->cinfo = cinfo;
587     /* create the J2K codec */
588     jp2->j2k = j2k_create_compress(cinfo);
589     if(jp2->j2k == NULL) {
590       jp2_destroy_compress(jp2);
591       return NULL;
592     }
593   }
594   return jp2;
595 }
596
597 void jp2_destroy_compress(opj_jp2_t *jp2) {
598   if(jp2) {
599     /* destroy the J2K codec */
600     j2k_destroy_compress(jp2->j2k);
601
602     if(jp2->comps) {
603       opj_free(jp2->comps);
604     }
605     if(jp2->cl) {
606       opj_free(jp2->cl);
607     }
608     opj_free(jp2);
609   }
610 }
611
612 void jp2_setup_encoder(opj_jp2_t *jp2, opj_cparameters_t *parameters, opj_image_t *image) {
613   int i;
614   int depth_0, sign;
615
616   if(!jp2 || !parameters || !image)
617     return;
618
619   /* setup the J2K codec */
620   /* ------------------- */
621
622   j2k_setup_encoder(jp2->j2k, parameters, image);
623
624   /* setup the JP2 codec */
625   /* ------------------- */
626   
627   /* Profile box */
628
629   jp2->brand = JP2_JP2;  /* BR */
630   jp2->minversion = 0;  /* MinV */
631   jp2->numcl = 1;
632   jp2->cl = (unsigned int*) opj_malloc(jp2->numcl * sizeof(unsigned int));
633   jp2->cl[0] = JP2_JP2;  /* CL0 : JP2 */
634
635   /* Image Header box */
636
637   jp2->numcomps = image->numcomps;  /* NC */
638   jp2->comps = (opj_jp2_comps_t*) opj_malloc(jp2->numcomps * sizeof(opj_jp2_comps_t));
639   jp2->h = image->y1 - image->y0;    /* HEIGHT */
640   jp2->w = image->x1 - image->x0;    /* WIDTH */
641   /* BPC */
642   depth_0 = image->comps[0].prec - 1;
643   sign = image->comps[0].sgnd;
644   jp2->bpc = depth_0 + (sign << 7);
645   for (i = 1; i < image->numcomps; i++) {
646     int depth = image->comps[i].prec - 1;
647     sign = image->comps[i].sgnd;
648     if (depth_0 != depth)
649       jp2->bpc = 255;
650   }
651   jp2->C = 7;      /* C : Always 7 */
652   jp2->UnkC = 0;    /* UnkC, colorspace specified in colr box */
653   jp2->IPR = 0;    /* IPR, no intellectual property */
654   
655   /* BitsPerComponent box */
656
657   for (i = 0; i < image->numcomps; i++) {
658     jp2->comps[i].bpcc = image->comps[i].prec - 1 + (image->comps[i].sgnd << 7);
659   }
660
661   /* Colour Specification box */
662
663   if ((image->numcomps == 1 || image->numcomps == 3) && (jp2->bpc != 255)) {
664     jp2->meth = 1;  /* METH: Enumerated colourspace */
665   } else {
666     jp2->meth = 2;  /* METH: Restricted ICC profile */
667   }
668   if (jp2->meth == 1) {
669     if (image->color_space == 1)
670       jp2->enumcs = 16;  /* sRGB as defined by IEC 61966\962\961 */
671     else if (image->color_space == 2)
672       jp2->enumcs = 17;  /* greyscale */
673     else if (image->color_space == 3)
674       jp2->enumcs = 18;  /* YUV */
675   } else {
676     jp2->enumcs = 0;    /* PROFILE (??) */
677   }
678   jp2->precedence = 0;  /* PRECEDENCE */
679   jp2->approx = 0;    /* APPROX */
680
681 }
682
683 bool jp2_encode(opj_jp2_t *jp2, opj_cio_t *cio, opj_image_t *image, char *index) {
684
685   /* JP2 encoding */
686
687   /* JPEG 2000 Signature box */
688   jp2_write_jp(cio);
689   /* File Type box */
690   jp2_write_ftyp(jp2, cio);
691   /* JP2 Header box */
692   jp2_write_jp2h(jp2, cio);
693
694   /* J2K encoding */
695
696   if(!jp2_write_jp2c(jp2, cio, image, index)) {
697     opj_event_msg(jp2->cinfo, EVT_ERROR, "Failed to encode image\n");
698     return false;
699   }
700
701   return true;
702 }
703
704