2 * Copyright (c) 1999-2000 Image Power, Inc. and the University of
4 * Copyright (c) 2001-2003 Michael David Adams.
8 /* __START_OF_JASPER_LICENSE__
10 * JasPer License Version 2.0
12 * Copyright (c) 1999-2000 Image Power, Inc.
13 * Copyright (c) 1999-2000 The University of British Columbia
14 * Copyright (c) 2001-2003 Michael David Adams
16 * All rights reserved.
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:
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.
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
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.
61 * __END_OF_JASPER_LICENSE__
67 * $Id: jp2_enc.c,v 1.1 2005/05/22 18:33:03 malaterre Exp $
70 /******************************************************************************\
72 \******************************************************************************/
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"
82 static uint_fast32_t jp2_gettypeasoc(int colorspace, int ctype);
83 static int clrspctojp2(jas_clrspc_t clrspc);
85 /******************************************************************************\
87 \******************************************************************************/
89 int jp2_encode(jas_image_t *image, jas_stream_t *out, char *optstr)
94 jas_stream_t *tmpstream;
101 uint_fast32_t overhead;
102 jp2_cdefchan_t *cdefchanent;
105 uint_fast32_t typeasoc;
106 jas_iccprof_t *iccprof;
107 jas_stream_t *iccstream;
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) {
127 /* Output the signature box. */
129 if (!(box = jp2_box_create(JP2_BOX_JP))) {
132 box->data.jp.magic = JP2_JP_MAGIC;
133 if (jp2_box_put(box, out)) {
136 jp2_box_destroy(box);
139 /* Output the file type box. */
141 if (!(box = jp2_box_create(JP2_BOX_FTYP))) {
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)) {
152 jp2_box_destroy(box);
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
162 if (!(tmpstream = jas_stream_memopen(0, 0))) {
166 /* Generate image header box. */
168 if (!(box = jp2_box_create(JP2_BOX_IHDR))) {
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;
180 if (jp2_box_put(box, tmpstream)) {
183 jp2_box_destroy(box);
186 /* Generate bits per component box. */
189 if (!(box = jp2_box_create(JP2_BOX_BPCC))) {
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)))) {
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));
202 if (jp2_box_put(box, tmpstream)) {
205 jp2_box_destroy(box);
209 /* Generate color specification box. */
211 if (!(box = jp2_box_create(JP2_BOX_COLR))) {
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;
225 colr->method = JP2_COLR_ICC;
226 colr->pri = JP2_COLR_PRI;
228 iccprof = jas_iccprof_createfromcmprof(jas_image_cmprof(image));
230 iccstream = jas_stream_memopen(0, 0);
232 if (jas_iccprof_save(iccprof, iccstream))
234 if ((pos = jas_stream_tell(iccstream)) < 0)
237 colr->iccp = jas_malloc(pos);
239 jas_stream_rewind(iccstream);
240 if (jas_stream_read(iccstream, colr->iccp, colr->iccplen) != colr->iccplen)
242 jas_stream_close(iccstream);
243 jas_iccprof_destroy(iccprof);
246 if (jp2_box_put(box, tmpstream)) {
249 jp2_box_destroy(box);
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))
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))
272 case JAS_CLRSPC_FAM_GRAY:
273 if (jas_image_cmpttype(image, 0) ==
274 JAS_IMAGE_CT_COLOR(JAS_IMAGE_CT_GRAY_Y))
283 if (!(box = jp2_box_create(JP2_BOX_CDEF))) {
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;
296 if (jp2_box_put(box, tmpstream)) {
299 jp2_box_destroy(box);
303 /* Determine the total length of the JP2 header box. */
305 len = jas_stream_tell(tmpstream);
306 jas_stream_rewind(tmpstream);
309 * Output the JP2 header box and all of the boxes which it contains.
312 if (!(box = jp2_box_create(JP2_BOX_JP2H))) {
315 box->len = len + JP2_BOX_HDRLEN;
316 if (jp2_box_put(box, out)) {
319 jp2_box_destroy(box);
322 if (jas_stream_copy(out, tmpstream, len)) {
326 jas_stream_close(tmpstream);
330 * Output the contiguous code stream box.
333 if (!(box = jp2_box_create(JP2_BOX_JP2C))) {
337 if (jp2_box_put(box, out)) {
340 jp2_box_destroy(box);
343 /* Output the JPEG-2000 code stream. */
345 overhead = jas_stream_getrwcount(out);
346 sprintf(buf, "%s\n_jp2overhead=%lu\n", (optstr ? optstr : ""),
347 (unsigned long) overhead);
349 if (jpc_encode(image, out, buf)) {
359 jp2_box_destroy(box);
362 jas_stream_close(tmpstream);
367 static uint_fast32_t jp2_gettypeasoc(int colorspace, int ctype)
372 if (ctype & JAS_IMAGE_CT_OPACITY) {
373 type = JP2_CDEF_TYPE_OPACITY;
374 asoc = JP2_CDEF_ASOC_ALL;
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;
387 case JAS_IMAGE_CT_RGB_G:
388 type = JP2_CDEF_TYPE_COLOR;
389 asoc = JP2_CDEF_RGB_G;
391 case JAS_IMAGE_CT_RGB_B:
392 type = JP2_CDEF_TYPE_COLOR;
393 asoc = JP2_CDEF_RGB_B;
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;
403 case JAS_IMAGE_CT_YCBCR_CB:
404 type = JP2_CDEF_TYPE_COLOR;
405 asoc = JP2_CDEF_YCBCR_CB;
407 case JAS_IMAGE_CT_YCBCR_CR:
408 type = JP2_CDEF_TYPE_COLOR;
409 asoc = JP2_CDEF_YCBCR_CR;
413 case JAS_CLRSPC_FAM_GRAY:
414 type = JP2_CDEF_TYPE_COLOR;
415 asoc = JP2_CDEF_GRAY_Y;
420 return (type << 16) | asoc;
423 static int clrspctojp2(jas_clrspc_t 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;