ENH: Do the proper thing for static/shared
[openjpeg.git] / 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�2�1 */
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