Update to 2.0.0 tree from current Fremantle build
[opencv] / 3rdparty / libjasper / jp2_enc.c
1 /*
2  * Copyright (c) 1999-2000 Image Power, Inc. and the University of
3  *   British Columbia.
4  * Copyright (c) 2001-2003 Michael David Adams.
5  * All rights reserved.
6  */
7
8 /* __START_OF_JASPER_LICENSE__
9  * 
10  * JasPer License Version 2.0
11  * 
12  * Copyright (c) 2001-2006 Michael David Adams
13  * Copyright (c) 1999-2000 Image Power, Inc.
14  * Copyright (c) 1999-2000 The University of British Columbia
15  * 
16  * All rights reserved.
17  * 
18  * Permission is hereby granted, free of charge, to any person (the
19  * "User") obtaining a copy of this software and associated documentation
20  * files (the "Software"), to deal in the Software without restriction,
21  * including without limitation the rights to use, copy, modify, merge,
22  * publish, distribute, and/or sell copies of the Software, and to permit
23  * persons to whom the Software is furnished to do so, subject to the
24  * following conditions:
25  * 
26  * 1.  The above copyright notices and this permission notice (which
27  * includes the disclaimer below) shall be included in all copies or
28  * substantial portions of the Software.
29  * 
30  * 2.  The name of a copyright holder shall not be used to endorse or
31  * promote products derived from the Software without specific prior
32  * written permission.
33  * 
34  * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS
35  * LICENSE.  NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER
36  * THIS DISCLAIMER.  THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS
37  * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
38  * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
39  * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.  IN NO
40  * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL
41  * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING
42  * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
43  * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
44  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.  NO ASSURANCES ARE
45  * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE
46  * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY.
47  * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS
48  * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL
49  * PROPERTY RIGHTS OR OTHERWISE.  AS A CONDITION TO EXERCISING THE RIGHTS
50  * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE
51  * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY.  THE SOFTWARE
52  * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL
53  * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES,
54  * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL
55  * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH
56  * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH,
57  * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH
58  * RISK ACTIVITIES").  THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY
59  * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES.
60  * 
61  * __END_OF_JASPER_LICENSE__
62  */
63
64 /*
65  * JP2 Library
66  *
67  * $Id: jp2_enc.c,v 1.2 2008-05-26 09:40:52 vp153 Exp $
68  */
69
70 /******************************************************************************\
71 * Includes.
72 \******************************************************************************/
73
74 #include <assert.h>
75 #include "jasper/jas_malloc.h"
76 #include "jasper/jas_image.h"
77 #include "jasper/jas_stream.h"
78 #include "jasper/jas_cm.h"
79 #include "jasper/jas_icc.h"
80 #include "jp2_cod.h"
81
82 static uint_fast32_t jp2_gettypeasoc(int colorspace, int ctype);
83 static int clrspctojp2(jas_clrspc_t clrspc);
84
85 /******************************************************************************\
86 * Functions.
87 \******************************************************************************/
88
89 int jp2_encode(jas_image_t *image, jas_stream_t *out, char *optstr)
90 {
91         jp2_box_t *box;
92         jp2_ftyp_t *ftyp;
93         jp2_ihdr_t *ihdr;
94         jas_stream_t *tmpstream;
95         int allcmptssame;
96         jp2_bpcc_t *bpcc;
97         long len;
98         uint_fast16_t cmptno;
99         jp2_colr_t *colr;
100         char buf[4096];
101         uint_fast32_t overhead;
102         jp2_cdefchan_t *cdefchanent;
103         jp2_cdef_t *cdef;
104         int i;
105         uint_fast32_t typeasoc;
106 jas_iccprof_t *iccprof;
107 jas_stream_t *iccstream;
108 int pos;
109 int needcdef;
110 int prec;
111 int sgnd;
112
113         box = 0;
114         tmpstream = 0;
115
116         allcmptssame = 1;
117         sgnd = jas_image_cmptsgnd(image, 0);
118         prec = jas_image_cmptprec(image, 0);
119         for (i = 1; i < jas_image_numcmpts(image); ++i) {
120                 if (jas_image_cmptsgnd(image, i) != sgnd ||
121                   jas_image_cmptprec(image, i) != prec) {
122                         allcmptssame = 0;
123                         break;
124                 }
125         }
126
127         /* Output the signature box. */
128
129         if (!(box = jp2_box_create(JP2_BOX_JP))) {
130                 goto error;
131         }
132         box->data.jp.magic = JP2_JP_MAGIC;
133         if (jp2_box_put(box, out)) {
134                 goto error;
135         }
136         jp2_box_destroy(box);
137         box = 0;
138
139         /* Output the file type box. */
140
141         if (!(box = jp2_box_create(JP2_BOX_FTYP))) {
142                 goto error;
143         }
144         ftyp = &box->data.ftyp;
145         ftyp->majver = JP2_FTYP_MAJVER;
146         ftyp->minver = JP2_FTYP_MINVER;
147         ftyp->numcompatcodes = 1;
148         ftyp->compatcodes[0] = JP2_FTYP_COMPATCODE;
149         if (jp2_box_put(box, out)) {
150                 goto error;
151         }
152         jp2_box_destroy(box);
153         box = 0;
154
155         /*
156          * Generate the data portion of the JP2 header box.
157          * We cannot simply output the header for this box
158          * since we do not yet know the correct value for the length
159          * field.
160          */
161
162         if (!(tmpstream = jas_stream_memopen(0, 0))) {
163                 goto error;
164         }
165
166         /* Generate image header box. */
167
168         if (!(box = jp2_box_create(JP2_BOX_IHDR))) {
169                 goto error;
170         }
171         ihdr = &box->data.ihdr;
172         ihdr->width = jas_image_width(image);
173         ihdr->height = jas_image_height(image);
174         ihdr->numcmpts = jas_image_numcmpts(image);
175         ihdr->bpc = allcmptssame ? JP2_SPTOBPC(jas_image_cmptsgnd(image, 0),
176           jas_image_cmptprec(image, 0)) : JP2_IHDR_BPCNULL;
177         ihdr->comptype = JP2_IHDR_COMPTYPE;
178         ihdr->csunk = 0;
179         ihdr->ipr = 0;
180         if (jp2_box_put(box, tmpstream)) {
181                 goto error;
182         }
183         jp2_box_destroy(box);
184         box = 0;
185
186         /* Generate bits per component box. */
187
188         if (!allcmptssame) {
189                 if (!(box = jp2_box_create(JP2_BOX_BPCC))) {
190                         goto error;
191                 }
192                 bpcc = &box->data.bpcc;
193                 bpcc->numcmpts = jas_image_numcmpts(image);
194                 if (!(bpcc->bpcs = jas_malloc(bpcc->numcmpts *
195                   sizeof(uint_fast8_t)))) {
196                         goto error;
197                 }
198                 for (cmptno = 0; cmptno < bpcc->numcmpts; ++cmptno) {
199                         bpcc->bpcs[cmptno] = JP2_SPTOBPC(jas_image_cmptsgnd(image,
200                           cmptno), jas_image_cmptprec(image, cmptno));
201                 }
202                 if (jp2_box_put(box, tmpstream)) {
203                         goto error;
204                 }
205                 jp2_box_destroy(box);
206                 box = 0;
207         }
208
209         /* Generate color specification box. */
210
211         if (!(box = jp2_box_create(JP2_BOX_COLR))) {
212                 goto error;
213         }
214         colr = &box->data.colr;
215         switch (jas_image_clrspc(image)) {
216         case JAS_CLRSPC_SRGB:
217         case JAS_CLRSPC_SYCBCR:
218         case JAS_CLRSPC_SGRAY:
219                 colr->method = JP2_COLR_ENUM;
220                 colr->csid = clrspctojp2(jas_image_clrspc(image));
221                 colr->pri = JP2_COLR_PRI;
222                 colr->approx = 0;
223                 break;
224         default:
225                 colr->method = JP2_COLR_ICC;
226                 colr->pri = JP2_COLR_PRI;
227                 colr->approx = 0;
228                 iccprof = jas_iccprof_createfromcmprof(jas_image_cmprof(image));
229                 assert(iccprof);
230                 iccstream = jas_stream_memopen(0, 0);
231                 assert(iccstream);
232                 if (jas_iccprof_save(iccprof, iccstream))
233                         abort();
234                 if ((pos = jas_stream_tell(iccstream)) < 0)
235                         abort();
236                 colr->iccplen = pos;
237                 colr->iccp = jas_malloc(pos);
238                 assert(colr->iccp);
239                 jas_stream_rewind(iccstream);
240                 if (jas_stream_read(iccstream, colr->iccp, colr->iccplen) != colr->iccplen)
241                         abort();
242                 jas_stream_close(iccstream);
243                 jas_iccprof_destroy(iccprof);
244                 break;
245         }
246         if (jp2_box_put(box, tmpstream)) {
247                 goto error;
248         }
249         jp2_box_destroy(box);
250         box = 0;
251
252         needcdef = 1;
253         switch (jas_clrspc_fam(jas_image_clrspc(image))) {
254         case JAS_CLRSPC_FAM_RGB:
255                 if (jas_image_cmpttype(image, 0) ==
256                   JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_R) &&
257                   jas_image_cmpttype(image, 1) ==
258                   JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_G) &&
259                   jas_image_cmpttype(image, 2) ==
260                   JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_B))
261                         needcdef = 0;
262                 break;
263         case JAS_CLRSPC_FAM_YCBCR:
264                 if (jas_image_cmpttype(image, 0) ==
265                   JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_YCBCR_Y) &&
266                   jas_image_cmpttype(image, 1) ==
267                   JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_YCBCR_CB) &&
268                   jas_image_cmpttype(image, 2) ==
269                   JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_YCBCR_CR))
270                         needcdef = 0;
271                 break;
272         case JAS_CLRSPC_FAM_GRAY:
273                 if (jas_image_cmpttype(image, 0) ==
274                   JAS_IMAGE_CT_COLOR(JAS_IMAGE_CT_GRAY_Y))
275                         needcdef = 0;
276                 break;
277         default:
278                 abort();
279                 break;
280         }
281
282         if (needcdef) {
283                 if (!(box = jp2_box_create(JP2_BOX_CDEF))) {
284                         goto error;
285                 }
286                 cdef = &box->data.cdef;
287                 cdef->numchans = jas_image_numcmpts(image);
288                 cdef->ents = jas_malloc(cdef->numchans * sizeof(jp2_cdefchan_t));
289                 for (i = 0; i < jas_image_numcmpts(image); ++i) {
290                         cdefchanent = &cdef->ents[i];
291                         cdefchanent->channo = i;
292                         typeasoc = jp2_gettypeasoc(jas_image_clrspc(image), jas_image_cmpttype(image, i));
293                         cdefchanent->type = typeasoc >> 16;
294                         cdefchanent->assoc = typeasoc & 0x7fff;
295                 }
296                 if (jp2_box_put(box, tmpstream)) {
297                         goto error;
298                 }
299                 jp2_box_destroy(box);
300                 box = 0;
301         }
302
303         /* Determine the total length of the JP2 header box. */
304
305         len = jas_stream_tell(tmpstream);
306         jas_stream_rewind(tmpstream);
307
308         /*
309          * Output the JP2 header box and all of the boxes which it contains.
310          */
311
312         if (!(box = jp2_box_create(JP2_BOX_JP2H))) {
313                 goto error;
314         }
315         box->len = len + JP2_BOX_HDRLEN(false);
316         if (jp2_box_put(box, out)) {
317                 goto error;
318         }
319         jp2_box_destroy(box);
320         box = 0;
321
322         if (jas_stream_copy(out, tmpstream, len)) {
323                 goto error;
324         }
325
326         jas_stream_close(tmpstream);
327         tmpstream = 0;
328
329         /*
330          * Output the contiguous code stream box.
331          */
332
333         if (!(box = jp2_box_create(JP2_BOX_JP2C))) {
334                 goto error;
335         }
336         box->len = 0;
337         if (jp2_box_put(box, out)) {
338                 goto error;
339         }
340         jp2_box_destroy(box);
341         box = 0;
342
343         /* Output the JPEG-2000 code stream. */
344
345         overhead = jas_stream_getrwcount(out);
346         sprintf(buf, "%s\n_jp2overhead=%lu\n", (optstr ? optstr : ""),
347           (unsigned long) overhead);
348
349         if (jpc_encode(image, out, buf)) {
350                 goto error;
351         }
352
353         return 0;
354         abort();
355
356 error:
357
358         if (box) {
359                 jp2_box_destroy(box);
360         }
361         if (tmpstream) {
362                 jas_stream_close(tmpstream);
363         }
364         return -1;
365 }
366
367 static uint_fast32_t jp2_gettypeasoc(int colorspace, int ctype)
368 {
369         int type;
370         int asoc;
371
372         if (ctype & JAS_IMAGE_CT_OPACITY) {
373                 type = JP2_CDEF_TYPE_OPACITY;
374                 asoc = JP2_CDEF_ASOC_ALL;
375                 goto done;
376         }
377
378         type = JP2_CDEF_TYPE_UNSPEC;
379         asoc = JP2_CDEF_ASOC_NONE;
380         switch (jas_clrspc_fam(colorspace)) {
381         case JAS_CLRSPC_FAM_RGB:
382                 switch (JAS_IMAGE_CT_COLOR(ctype)) {
383                 case JAS_IMAGE_CT_RGB_R:
384                         type = JP2_CDEF_TYPE_COLOR;
385                         asoc = JP2_CDEF_RGB_R;
386                         break;
387                 case JAS_IMAGE_CT_RGB_G:
388                         type = JP2_CDEF_TYPE_COLOR;
389                         asoc = JP2_CDEF_RGB_G;
390                         break;
391                 case JAS_IMAGE_CT_RGB_B:
392                         type = JP2_CDEF_TYPE_COLOR;
393                         asoc = JP2_CDEF_RGB_B;
394                         break;
395                 }
396                 break;
397         case JAS_CLRSPC_FAM_YCBCR:
398                 switch (JAS_IMAGE_CT_COLOR(ctype)) {
399                 case JAS_IMAGE_CT_YCBCR_Y:
400                         type = JP2_CDEF_TYPE_COLOR;
401                         asoc = JP2_CDEF_YCBCR_Y;
402                         break;
403                 case JAS_IMAGE_CT_YCBCR_CB:
404                         type = JP2_CDEF_TYPE_COLOR;
405                         asoc = JP2_CDEF_YCBCR_CB;
406                         break;
407                 case JAS_IMAGE_CT_YCBCR_CR:
408                         type = JP2_CDEF_TYPE_COLOR;
409                         asoc = JP2_CDEF_YCBCR_CR;
410                         break;
411                 }
412                 break;
413         case JAS_CLRSPC_FAM_GRAY:
414                 type = JP2_CDEF_TYPE_COLOR;
415                 asoc = JP2_CDEF_GRAY_Y;
416                 break;
417         }
418
419 done:
420         return (type << 16) | asoc;
421 }
422
423 static int clrspctojp2(jas_clrspc_t clrspc)
424 {
425         switch (clrspc) {
426         case JAS_CLRSPC_SRGB:
427                 return JP2_COLR_SRGB;
428         case JAS_CLRSPC_SYCBCR:
429                 return JP2_COLR_SYCC;
430         case JAS_CLRSPC_SGRAY:
431                 return JP2_COLR_SGRAY;
432         default:
433                 abort();
434                 break;
435         }
436 }